当前位置: 首页 > article >正文

PL端:HDMI 输出实验

实验环境

vivado 2024.1

实验任务

做一个 HDMI 输出的彩条

硬件介绍

开发板没有HDMI编码芯片,是将FPGA的3.3差分IO直接连接到HDMI连接器,FPGA 完成 24 位 RGB 编码输出TMDS 差分信号。
在这里插入图片描述
HDMI传输要素:
在这里插入图片描述

TMDS 差分信号

TMDS(Transition Minimized Differential Signaling)即过渡调制差分信号,也被称为最小化传输差分信号,具有以下特点:
编码方式:
通过异或及异或非等逻辑算法将原始的 8 位信号数据转换成 10 位。前 8 位数据由原始信号经运算后获得,第 9 位指示运算的方式,第 10 位用来实现直流平衡(DC-balanced)。这种编码方式使得被传输信号过渡过程的上冲和下冲减小,能保证信道中直流偏移为零,让电平转化实现不同逻辑接口间的匹配。
传输模式:
差分信号传输:TMDS 采用差分传动技术,利用两个引脚间的电压差来传送信号。传输数据的数值(“0” 或者 “1”)由两脚间电压正负极性和大小决定。即采用 2 根线来传输信号,一根线上传输原来的信号,另一根线上传输与原来信号相反的信号。接收端通过让一根线上的信号减去另一根线上的信号的方式来屏蔽电磁干扰,从而得到正确的信号。这种方式可以减少信号对传输线的电磁干扰,提高信号传输的可靠性。
串行传输:和 LVDS 相似,TMDS 是一个串行的传输设计,这意味着数据是一位一位按顺序传输的,能够在较长的距离上实现高速数据传输。
应用领域:TMDS 技术主要应用于 DVI(Digital Visual Interface)和 HDMI(High Definition Multimedia Interface)等视频接口。在这些接口中,TMDS 链路包括 3 个传输 RGB 信号的数据通道和 1 个传输时钟信号的通道。例如,HDMI 把视频信号分为 R、G、B、H、V 五种信号用 TMDS 技术编码,其中 HV 编码在 B 信号通道里面传输,R、G 的多余位置用来传输音频信号。
总之,TMDS 差分信号技术通过独特的编码和传输方式,实现了高速、可靠的数据传输,在高清视频传输领域得到了广泛应用。

Vivado 工程建立

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

添加 HDMI 编码器 IP 核

很多人都熟知 VGA 的数据是 RGB 数据,而 HDMI 使用的是 TMDS 差分信号。在 FPGA 中,RGB 数据操作起来相对容易。所以,我们的任务就是将 RGB 数据转换为 HDMI 的 TMDS 差分信号。基于此,我们采用了 RGB to DVI 的 IP,这是因为 DVI 和 HDMI 所使用的都是 TMDS 信号。

复制 repo 文件夹,别的厂家提供的HDMI 编码器的 IP
在这里插入图片描述

点击“IP Catalog”,添加IP
在这里插入图片描述
路径选择刚才复制的 repo 文件夹
在这里插入图片描述
添加 IP 成功提示添加了多少个 IP
在这里插入图片描述
搜索“RGB to DVI Video Encoder(Source)”,双击
在这里插入图片描述
保持默认,点击OK
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

看到一个名为 rgb2dvi_0
在这里插入图片描述

添加像素时钟 PLL 模块

驱动 HDMI 编码器,需要提供像素时钟和 5 倍像素时钟,5 倍像素时钟用于 10:1 串行化

在“IP Catlog”窗口搜索关键字“clock”,双击“Clocking Wizard”
在这里插入图片描述
在“Component Name”中填写“video_clock”,“clk_in1”填写
50,这里 50Mhz 和开发板 PL 端晶振频率一致。
在这里插入图片描述

输出时钟“clk_out1”用于视频像素时钟,这里填写 74.25,这是 1280x720@60 分辨率的像素时钟,每一种分辨率的像素时钟都不同,需要非常了解视频标准才能知道每一种视频分辨率的像素时钟,“clk_out2”用于编码器串行化,像素时钟的 5 倍,这里填写 371.25,然后点击“OK”生成 IP。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

添加彩条发生模块

彩条发生模块是一段 Verilog 代码,用于产生视频时序和水平方向的 8 个彩条
主要是理解代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/11/06 13:09:03
// Design Name: 
// Module Name: color_bar
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module color_bar(
	input clk,            //����ʱ�����룬1280x720@60P������ʱ��Ϊ74.25
	input rst,            //��λ,����Ч
	output hs,            //��ͬ��������Ч
	output vs,            //��ͬ��������Ч
	output de,            //������Ч
	output[7:0] rgb_r,    //�������ݡ���ɫ����
	output[7:0] rgb_g,    //�������ݡ���ɫ����
	output[7:0] rgb_b     //�������ݡ���ɫ����
);
/*********��Ƶʱ���������******************************************/
parameter H_ACTIVE = 16'd1280;  //����Ч���ȣ�����ʱ�����ڸ�����
parameter H_FP = 16'd110;       //��ͬ��ǰ�糤��
parameter H_SYNC = 16'd40;      //��ͬ������
parameter H_BP = 16'd220;       //��ͬ����糤��
parameter V_ACTIVE = 16'd720;   //����Ч���ȣ��еĸ�����
parameter V_FP 	= 16'd5;        //��ͬ��ǰ�糤��
parameter V_SYNC  = 16'd5;      //��ͬ������
parameter V_BP	= 16'd20;       //��ͬ����糤��

//parameter H_ACTIVE = 16'd1920;
//parameter H_FP = 16'd88;
//parameter H_SYNC = 16'd44;
//parameter H_BP = 16'd148; 
//parameter V_ACTIVE = 16'd1080;
//parameter V_FP 	= 16'd4;
//parameter V_SYNC  = 16'd5;
//parameter V_BP	= 16'd36;
parameter H_TOTAL = H_ACTIVE + H_FP + H_SYNC + H_BP;//���ܳ���
parameter V_TOTAL = V_ACTIVE + V_FP + V_SYNC + V_BP;//���ܳ���
/*********����RGB color bar��ɫ��������*****************************/
parameter WHITE_R 		= 8'hff;
parameter WHITE_G 		= 8'hff;
parameter WHITE_B 		= 8'hff;
parameter YELLOW_R 		= 8'hff;
parameter YELLOW_G 		= 8'hff;
parameter YELLOW_B 		= 8'h00;                              	
parameter CYAN_R 		= 8'h00;
parameter CYAN_G 		= 8'hff;
parameter CYAN_B 		= 8'hff;                             	
parameter GREEN_R 		= 8'h00;
parameter GREEN_G 		= 8'hff;
parameter GREEN_B 		= 8'h00;
parameter MAGENTA_R 	= 8'hff;
parameter MAGENTA_G 	= 8'h00;
parameter MAGENTA_B 	= 8'hff;
parameter RED_R 		= 8'hff;
parameter RED_G 		= 8'h00;
parameter RED_B 		= 8'h00;
parameter BLUE_R 		= 8'h00;
parameter BLUE_G 		= 8'h00;
parameter BLUE_B 		= 8'hff;
parameter BLACK_R 		= 8'h00;
parameter BLACK_G 		= 8'h00;
parameter BLACK_B 		= 8'h00;
reg hs_reg;//����һ���Ĵ���,������ͬ��
reg vs_reg;//����һ���Ĵ���,�û���ͬ��
reg hs_reg_d0;//hs_regһ��ʱ�ӵ��ӳ�
              //������_d0��d1��d2��Ϊ��׺�ľ�Ϊij���Ĵ������ӳ�
reg vs_reg_d0;//vs_regһ��ʱ�ӵ��ӳ�
reg[11:0] h_cnt;//�����еļ�����
reg[11:0] v_cnt;//���ڳ���֡���ļ�����
reg[11:0] active_x;//��Чͼ��ĵ�����x
reg[11:0] active_y;//��Чͼ�������y
reg[7:0] rgb_r_reg;//��������r����
reg[7:0] rgb_g_reg;//��������g����
reg[7:0] rgb_b_reg;//��������b����
reg h_active;//��ͼ����Ч
reg v_active;//��ͼ����Ч
wire video_active;//һ֡��ͼ�����Ч����h_active & v_active
reg video_active_d0;
assign hs = hs_reg_d0;
assign vs = vs_reg_d0;
assign video_active = h_active & v_active;
assign de = video_active_d0;
assign rgb_r = rgb_r_reg;
assign rgb_g = rgb_g_reg;
assign rgb_b = rgb_b_reg;
always@(posedge clk or posedge rst)
begin
	if(rst)
		begin
			hs_reg_d0 <= 1'b0;
			vs_reg_d0 <= 1'b0;
			video_active_d0 <= 1'b0;
		end
	else
		begin
			hs_reg_d0 <= hs_reg;
			vs_reg_d0 <= vs_reg;
			video_active_d0 <= video_active;
		end
end

always@(posedge clk or posedge rst)
begin
	if(rst)
		h_cnt <= 12'd0;
	else if(h_cnt == H_TOTAL - 1)//�м����������ֵ����
		h_cnt <= 12'd0;
	else
		h_cnt <= h_cnt + 12'd1;
end

always@(posedge clk or posedge rst)
begin
	if(rst)
		active_x <= 12'd0;
	else if(h_cnt >= H_FP + H_SYNC + H_BP - 1)//����ͼ���x����
		active_x <= h_cnt - (H_FP[11:0] + H_SYNC[11:0] + H_BP[11:0] - 12'd1);
	else
		active_x <= active_x;
end

always@(posedge clk or posedge rst)
begin
	if(rst)
		v_cnt <= 12'd0;
	else if(h_cnt == H_FP  - 1)//������������ΪH_FP - 1��ʱ�򳡼�����+1������
		if(v_cnt == V_TOTAL - 1)//�������������ֵ�ˣ�����
			v_cnt <= 12'd0;
		else
			v_cnt <= v_cnt + 12'd1;//û�����ֵ��+1
	else
		v_cnt <= v_cnt;
end

always@(posedge clk or posedge rst)
begin
	if(rst)
		hs_reg <= 1'b0;
	else if(h_cnt == H_FP - 1)//��ͬ����ʼ��...
		hs_reg <= 1'b1;
	else if(h_cnt == H_FP + H_SYNC - 1)//��ͬ����ʱ��Ҫ������
		hs_reg <= 1'b0;
	else
		hs_reg <= hs_reg;
end

always@(posedge clk or posedge rst)
begin
	if(rst)
		h_active <= 1'b0;
	else if(h_cnt == H_FP + H_SYNC + H_BP - 1)
		h_active <= 1'b1;
	else if(h_cnt == H_TOTAL - 1)
		h_active <= 1'b0;
	else
		h_active <= h_active;
end

always@(posedge clk or posedge rst)
begin
	if(rst)
		vs_reg <= 1'd0;
	else if((v_cnt == V_FP - 1) && (h_cnt == H_FP - 1))
		vs_reg <= 1'b1;
	else if((v_cnt == V_FP + V_SYNC - 1) && (h_cnt == H_FP - 1))
		vs_reg <= 1'b0;	
	else
		vs_reg <= vs_reg;
end

always@(posedge clk or posedge rst)
begin
	if(rst)
		v_active <= 1'd0;
	else if((v_cnt == V_FP + V_SYNC + V_BP - 1) && (h_cnt == H_FP - 1))
		v_active <= 1'b1;
	else if((v_cnt == V_TOTAL - 1) && (h_cnt == H_FP - 1))
		v_active <= 1'b0;	
	else
		v_active <= v_active;
end

always@(posedge clk or posedge rst)
begin
	if(rst)
		begin
			rgb_r_reg <= 8'h00;
			rgb_g_reg <= 8'h00;
			rgb_b_reg <= 8'h00;
		end
	else if(video_active)
		if(active_x == 12'd0)
			begin
				rgb_r_reg <= WHITE_R;
				rgb_g_reg <= WHITE_G;
				rgb_b_reg <= WHITE_B;
			end
		else if(active_x == (H_ACTIVE/8) * 1)
			begin
				rgb_r_reg <= YELLOW_R;
				rgb_g_reg <= YELLOW_G;
				rgb_b_reg <= YELLOW_B;
			end			
		else if(active_x == (H_ACTIVE/8) * 2)
			begin
				rgb_r_reg <= CYAN_R;
				rgb_g_reg <= CYAN_G;
				rgb_b_reg <= CYAN_B;
			end
		else if(active_x == (H_ACTIVE/8) * 3)
			begin
				rgb_r_reg <= GREEN_R;
				rgb_g_reg <= GREEN_G;
				rgb_b_reg <= GREEN_B;
			end
		else if(active_x == (H_ACTIVE/8) * 4)
			begin
				rgb_r_reg <= MAGENTA_R;
				rgb_g_reg <= MAGENTA_G;
				rgb_b_reg <= MAGENTA_B;
			end
		else if(active_x == (H_ACTIVE/8) * 5)
			begin
				rgb_r_reg <= RED_R;
				rgb_g_reg <= RED_G;
				rgb_b_reg <= RED_B;
			end
		else if(active_x == (H_ACTIVE/8) * 6)
			begin
				rgb_r_reg <= BLUE_R;
				rgb_g_reg <= BLUE_G;
				rgb_b_reg <= BLUE_B;
			end	
		else if(active_x == (H_ACTIVE/8) * 7)
			begin
				rgb_r_reg <= BLACK_R;
				rgb_g_reg <= BLACK_G;
				rgb_b_reg <= BLACK_B;
			end
		else
			begin
				rgb_r_reg <= rgb_r_reg;
				rgb_g_reg <= rgb_g_reg;
				rgb_b_reg <= rgb_b_reg;
			end			
	else
		begin
			rgb_r_reg <= 8'h00;
			rgb_g_reg <= 8'h00;
			rgb_b_reg <= 8'h00;
		end
end

endmodule 

添加顶层模块

top 模块例化了彩条发生模块,HDMI 编码模块,和像素时钟生成模块
将hdmi_out_test.srcs\sources_1\new的top文件copy过来,然后点击添加现有资源文件
在这里插入图片描述

添加 XDC 约束文件

点击“Run Synthesis”开始综合
在这里插入图片描述
综合完成以后点击“Cancel”

在这里插入图片描述
点击“Constraints Wizard”
在这里插入图片描述
在弹出的窗口中点击“Next”
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

set_property PACKAGE_PIN U18 [get_ports {sys_clk}]
set_property IOSTANDARD LVCMOS33 [get_ports {sys_clk}]
create_clock -period 20.000 -waveform {0.000 10.000} [get_ports sys_clk]
set_property IOSTANDARD TMDS_33 [get_ports TMDS_clk_n]
set_property PACKAGE_PIN U13 [get_ports TMDS_clk_p]
set_property IOSTANDARD TMDS_33 [get_ports TMDS_clk_p]
set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_n[0]}]
set_property PACKAGE_PIN W14 [get_ports {TMDS_data_p[0]}]
set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_p[0]}]
set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_n[1]}]
set_property PACKAGE_PIN Y18 [get_ports {TMDS_data_p[1]}]
set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_p[1]}]
set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_n[2]}]
set_property PACKAGE_PIN Y16 [get_ports {TMDS_data_p[2]}]
set_property IOSTANDARD TMDS_33 [get_ports {TMDS_data_p[2]}]
set_property PACKAGE_PIN V16 [get_ports hdmi_oen]
set_property IOSTANDARD LVCMOS33 [get_ports hdmi_oen]

下载调试

编译生成 bit 文件
在这里插入图片描述
在这里插入图片描述
需要注意,这里使用1280x720@60Hz
在这里插入图片描述
显示屏显示结果

在这里插入图片描述

总结

1、学会使用第三点IP核,首先是添加,后面的使用和自带IP核操作一致。
2、主要还是在梳理vivado使用流程。

参考

《cource_s1_ALINX_ZYNQ(AX7Z010_AX7Z020)开发平台基础教程V1.04.pdf》


http://www.kler.cn/a/387787.html

相关文章:

  • 利用 Screen 保持 VSCode 连接远程任务持续运行
  • Dial-insight:利用高质量特定领域数据微调大型语言模型防止灾难性遗忘
  • 论文阅读《机器人状态估计中的李群》
  • OLED 显示画面的变换操作——上下、左右翻转
  • 大数据新视界 -- 大数据大厂之 Impala 性能优化:优化数据加载的实战技巧(下)(16/30)
  • 「QT」几何数据类 之 QLine 整型直线类
  • XMLHttpRequest以及Promise对象的使用
  • adb:Android调试桥
  • 揭秘云计算 | 2、业务需求推动IT发展
  • 单相锁相环,原理与Matlab实现
  • 【ECCV2024】V-IRL: Grounding Virtual Intelligence in Real Life
  • 海量数据迁移:Elasticsearch到OpenSearch的无缝迁移策略与实践
  • 【优选算法篇】微位至简,数之恢宏——解构 C++ 位运算中的理与美
  • uni-app小程序开发(1)
  • 【大模型】Spring AI Alibaba 对接百炼平台大模型使用详解
  • CX_SY_OPEN_SQL_DB
  • leetcode92:反转链表||
  • C#入门 017 字段,属性,索引器,常量
  • R语言*号标识显著性差异判断组间差异是否具有统计意义
  • 5. Redis的 安全与性能优化
  • ubuntu问题 -- ubuntu图形化桌面突然打不开了, 一开机黑屏, 或者直接就是login登录的tty命令行界面
  • S32G-VNP-RDB2开发环境搭建
  • 【贪心】【哈希】个人练习-Leetcode-1296. Divide Array in Sets of K Consecutive Numbers
  • 【数据库系统概论】第3章 SQL(三)数据更新
  • 将Go项目编译为可执行文件(windows/linux)
  • Web 开发新趋势下,GET 请求与 POST 请求如何抉择