FPGA纯verilog手写HDMI发送IP 提供源码和技术支持
目录
- 1、前言
- 2、设计思路和框架
- TMDS 编码算法
- OSERDESE串并转换
- 3、顶层源码和IP封装
- 4、源码和IP获取
1、前言
本设计使用Xilinx原语和自己手写的代码实现了HDMI发送功能,纯verilog手写,有源码,也提供封装好的IP,你喜欢用例化的方式就用源码,你喜欢搭建BD工程就用IP,目前IP的适应器件为zynq,如果是用7系列FPGA的兄弟可以改一下芯片型号即可使用。
这个HDMI发送模块我已在项目中多次使用,稳定性和实用性可以保证,最大支持1080P@60Hz帧率。
本文详细描述了设计方案,工程代码编译通过后上板调试验证,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
关于HDMI的理论介绍这里不多说,请自行搜索,很简单,本文只讲如何代码层级实现的干货。
2、设计思路和框架
HDMI编码框图如下:
Encoder 模块负责对数据进行编码,Serializer 模块对编码后的数据进行并串转换,最后
通过 OBUFDS 转化成 TMDS 差分信号传输。
整个系统需要两个输入时钟,一个是视频的像素时钟 Pixel Clk,另外一个时钟 Pixel Clk x5 的频率是像
素时钟的五倍。由前面的简介部分我们知道,并串转换过程的实现的是 10:1 的转换率,理论上转换器需要一个 10 倍像素时钟频率的串行时钟。这里我们只用了一个 5 倍的时钟频率,这是因为 OSERDESE2 模块可以实现 DDR 的功能,即它在五倍时钟频率的基础上又实现了双倍数据速率。
TMDS 连接的时钟通道我们采用与数据通道相同的并转串逻辑来实现。通过对 10 位二进制序列10’b11111_00000 在 10 倍像素时钟频率下进行并串转换,就可以得到像素时钟频率下的 TMDS 参考时钟。
另外需要注意的是,图中左下脚 HDMI 的音频/附加数据输入在本次实验中并未用到,因此以虚线表示。
TMDS 编码算法
Encoder 模块完成TMDS 编码算法,dvi_encoder 模块按照 DVI 接口规范中 TMDS 编码算法对输入的 8 位像素数据以及 2 位行场同步信号进行编码。该模块是 Xilinx 应用笔记 XAPP460 中所提供的编码模块,其具体实现的编码算法如下图所示:
TMDS 通过逻辑算法将 8 位字符数据通过最小转换编码为 10 位字符数据,前 8 位数据由原始信号经运
算后获得,第 9 位表示运算的方式,1 表示异或 0 表示异或非。经过 DC 平衡后(第 10 位),采用差分信号传输数据。第 10 位实际是一个反转标志位,1 表示进行了反转而 0 表示没有反转,从而达到 DC 平衡。
接收端在收到信号后,再进行相反的运算。TMDS 和 LVDS、TTL 相比有较好的电磁兼容性能。这种算
法可以减小传输信号过程的上冲和下冲,而 DC 平衡使信号对传输线的电磁干扰减少,可以用低成本的专用电缆实现长距离、高质量的数字信号传输。
算法中各个参数的含义如下图所示:
Encoder 模块顶层接口如下:
module dvi_encoder (input clkin, // pixel clock inputinput rstin, // async. reset input (active high)input [7:0] din , // data inputs: expect registeredinput c0 , // c0 inputinput c1 , // c1 inputinput de , // de inputoutput reg [9:0] dout // data outputs
);
代码部分并不复杂,就是将TMDS 编码算法的流程图翻译成了 verilog语言。
OSERDESE串并转换
TMDS 编码之后的数据由 Serializer 模块进行并串转换,通过调用 OSERDESE2 原语来实现 10:1 的并串转换。原语是 Xilinx 器件底层硬件中的功能模块,它使用专用的资源来实现一系列的功能。相比于 IP 核,原语的调用方法更简单,但是一般只用于实现一些简单的功能。
需要注意的是,一个 OSERDESE2 只能实现最多 8:1 的转换率,在这里我们通过位宽扩展实现了 10:1
的并串转换,如下图所示:
OSERDESE2 位宽扩展通过两个 OSERDESE2 模块来实现,其中一个作为 Master,
另一个作为 Slave,通过这种方式最多可实现 14:1 的并串转换。需要注意的是,在位宽扩展时,Slave 模块的数据输入端只能使用 D3 至 D8。
OSERDESE串并转换模块顶层接口如下:
module serializer_10_to_1(input reset, input paralell_clk, input serial_clk_5x, input [9:0] paralell_data, output serial_data_out );
3、顶层源码和IP封装
将各个功能模块进行例化,即完成了本设计,为了适应不同的使用需求,提供源码的同时也将源码进行了IP封装,两者一并提供。
顶层源码如下:
module helai_hdmi_out(input clk_hdmi ,input clk_hdmix5 ,input reset_n ,input i_vga_hs ,input i_vga_vs ,input i_vga_de , input [23:0] i_vga_rgb , output o_hdmi_clk_p ,output o_hdmi_clk_n ,output [2: 0] o_hdmi_data_p,output [2: 0] o_hdmi_data_n
);wire reset;//²¢ÐÐÊý¾Ý
wire [9:0] red_10bit;
wire [9:0] green_10bit;
wire [9:0] blue_10bit;
wire [9:0] clk_10bit; //´®ÐÐÊý¾Ý
wire [2:0] tmds_data_serial;
wire tmds_clk_serial;//*****************************************************
//** main code
//*****************************************************
assign clk_10bit = 10'b1111100000;//Òì²½¸´Î»£¬Í¬²½ÊÍ·Å
asyn_rst_syn reset_syn(.reset_n (reset_n),.clk (clk_hdmi),.syn_reset (reset) //¸ßÓÐЧ);//¶ÔÈý¸öÑÕɫͨµÀ½øÐбàÂë
dvi_encoder encoder_b (.clkin (clk_hdmi),.rstin (reset),.din (i_vga_rgb[7:0]),.c0 (i_vga_hs),.c1 (i_vga_vs),.de (i_vga_de),.dout (blue_10bit)) ;dvi_encoder encoder_g (.clkin (clk_hdmi),.rstin (reset),.din (i_vga_rgb[15:8]),.c0 (i_vga_hs),.c1 (i_vga_vs),.de (i_vga_de),.dout (green_10bit)) ;dvi_encoder encoder_r (.clkin (clk_hdmi),.rstin (reset),.din (i_vga_rgb[23:16]),.c0 (i_vga_hs),.c1 (i_vga_vs),.de (i_vga_de),.dout (red_10bit)) ;//¶Ô±àÂëºóµÄÊý¾Ý½øÐв¢´®×ª»»
serializer_10_to_1 serializer_b(.reset (reset), // ¸´Î»,¸ßÓÐЧ.paralell_clk (clk_hdmi), // ÊäÈë²¢ÐÐÊý¾ÝʱÖÓ.serial_clk_5x (clk_hdmix5), // ÊäÈë´®ÐÐÊý¾ÝʱÖÓ.paralell_data (blue_10bit), // ÊäÈë²¢ÐÐÊý¾Ý
// .paralell_data (10'h146), // ÊäÈë²¢ÐÐÊý¾Ý.serial_data_out (tmds_data_serial[0]) // Êä³ö´®ÐÐÊý¾Ý); serializer_10_to_1 serializer_g(.reset (reset),.paralell_clk (clk_hdmi),.serial_clk_5x (clk_hdmix5),.paralell_data (green_10bit),// .paralell_data (10'h146), .serial_data_out (tmds_data_serial[1]));serializer_10_to_1 serializer_r(.reset (reset),.paralell_clk (clk_hdmi),.serial_clk_5x (clk_hdmix5),.paralell_data (red_10bit),// .paralell_data (10'h146), .serial_data_out (tmds_data_serial[2]));serializer_10_to_1 serializer_clk(.reset (reset),.paralell_clk (clk_hdmi),.serial_clk_5x (clk_hdmix5),.paralell_data (clk_10bit),.serial_data_out (tmds_clk_serial));//ת»»²î·ÖÐźÅ
OBUFDS #(.IOSTANDARD ("TMDS_33") // I/Oµçƽ±ê׼ΪTMDS
) TMDS0 (.I (tmds_data_serial[0]),.O (o_hdmi_data_p[0]),.OB (o_hdmi_data_n[0])
);OBUFDS #(.IOSTANDARD ("TMDS_33") // I/Oµçƽ±ê׼ΪTMDS
) TMDS1 (.I (tmds_data_serial[1]),.O (o_hdmi_data_p[1]),.OB (o_hdmi_data_n[1])
);OBUFDS #(.IOSTANDARD ("TMDS_33") // I/Oµçƽ±ê׼ΪTMDS
) TMDS2 (.I (tmds_data_serial[2]), .O (o_hdmi_data_p[2]), .OB (o_hdmi_data_n[2])
);OBUFDS #(.IOSTANDARD ("TMDS_33") // I/Oµçƽ±ê׼ΪTMDS
) TMDS3 (.I (tmds_clk_serial), .O (o_hdmi_clk_p),.OB (o_hdmi_clk_n)
);endmodule
封装后的IP如下:

4、源码和IP获取
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:点击获取
网盘资料如下:


相关文章:
FPGA纯verilog手写HDMI发送IP 提供源码和技术支持
目录1、前言2、设计思路和框架TMDS 编码算法OSERDESE串并转换3、顶层源码和IP封装4、源码和IP获取1、前言 本设计使用Xilinx原语和自己手写的代码实现了HDMI发送功能,纯verilog手写,有源码,也提供封装好的IP,你喜欢用例化的方式就…...
【知识点】OkHttp 原理 8 连问
前言OkHttp可以说是Android开发中最常见的网络请求框架,OkHttp使用方便,扩展性强,功能强大,OKHttp源码与原理也是面试中的常客但是OKHttp的源码内容比较多,想要学习它的源码往往千头万绪,一时抓不住重点.本文从几个问题…...
【python】深入了解Selenium-PageObject
1、PageObject 定义 Page Object(简称PO)模式,是Selenium实战中最为流行,并且是自动化测试中最为熟悉和推崇的一种设计模式。在设计自动化测试时,把页面元素和元素的操作方法按照页面抽象出来,分离成一定的对象,然后再…...
PAT——7-4 简易测谎 (20 分)
测谎通常使用一套准备好的问题提问被测试者,通过分析被测试者的反应得到结果。比较高级的测谎技术会使用测谎仪,监视被测试者的生理活动状况。我们这里的简易测谎则是通过对问题答案的特征分析来做出判断。 首先我们要求被测试者做完 N 道单选题&#x…...
【力扣】 面试题 05.02.二进制数转字符串(超过c++100%)
二进制数转字符串。给定一个介于0和1之间的实数(如0.72),类型为double,打印它的二进制表达式。如果该数字无法精确地用32位以内的二进制表示,则打印“ERROR”。示例1:输入:0.625输出:"0.10…...
软件质量保证与测试 课堂笔记
...
Costco好市多验厂百问百答
【Costco好市多验厂百问百答】美国仓储式超市Costco,中文好市多,近几年发展势头迅猛,大有赶超传统商超巨头沃尔玛之势。之前有出口企业反馈,Costco采购不仅量大,而且价格好,所以Costco成为国内出口企业纷纷…...
Nginx 通过 header 中的标识进行分发
Nginx可以根据请求头中自定义的标识将请求分发到不同的服务器。具体来说,可以使用map指令将请求头中的自定义标识映射为不同的后端服务器地址,然后使用proxy_pass指令将请求转发到对应的后端服务器。 以下是一个示例配置文件: http {map $h…...
如何实现《电子签名法》要求的可靠电子签名?
电子文档的电子签名怎么弄?我们在工作中经常需要在一些Word、pdf等电子版文件中插入签名,而很多人可能不知道,电子签名怎么弄?怎么做电子签名才有效?电子印章或签名图片属于电子签名吗?当工作或商务交易中&…...
工程项目管理软件有哪些?这六款很好用!
工程项目管理软件哪个好用?这六款很不错! 在现代社会中,软件已经成为了企业信息化、项目管理等方面必不可少的工具。尤其是对于工程项目管理而言,借助软件进行协同、计划、控制等方面的工作,已经成为了必要的手段。但…...
多看看spdk代码学习
多看看spdk代码学习还是干货直接上代码简易讲解详细讲解一下这份代码还是干货直接上代码 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <signal.h> #include <stdbo…...
宾语从句it做形式主语的句子
It代替从句作形式主语的常见句型 一、it 代替连词 that 引导的从句作形式主语。 1、it be 过去分词 that 从句: It’s said that Tom has come back from abroad . It was reported that dozens of children died in the accident . 可用于该句型的过去分词还有…...
【C#基础】C# 文件与IO
序号系列文章9【C# 基础】C# 异常处理操作10【C#基础】C# 正则表达式11【C#基础】C# 预处理器指令文章目录前言1,文件和IO的概念2,文本文件操作2.1 File 类2.2 FileInfo 类2.3 FileStream 类2.4 StreamReader 类2.5 StreamWriter 类FileStream 和 Stream…...
死锁相关介绍【内含哲学家就餐问题】
死锁 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 场景1:一个线程,一把锁 一个线程,一把锁,线程…...
Java的Groovy执行器内存泄露(MetaSpace)问题分析与解决办法
环境与背景 在java程序中通过GroovyScriptEvaluator执行器创建脚本Script对象调用Groovy脚本语言来完成某些功能, ,会通过AppClassLoader或者GroovyClassLoader去生产一个随机的名称的Groovy的Script类对象,导致元数据,产生的class类会被AppClassLoader或者GroovyClassLoader内…...
【linux】进程信号——信号的产生
进程信号一、信号概念1.1 信号理解二、产生信号2.1 通过键盘产生信号2.2 捕捉信号自定义signal2.3 系统调用接口产生信号2.3.1 向任意进程发送任意信号kill2.3.2 给自己发送任意信号raise2.3.3 给自己发送指定信号abort2.3.4 理解2.4 硬件异常产生信号2.4.1 除0异常2.4.2 野指针…...
部署OpenStack
部署 1. 环境配置 配置主机名 使用CRT软件连接controller节点和compute节点,用户名默认为root,密码默认为000000。连接上之后,使用linux命令修改节点主机名。 [rootcontroller ~]# hostnamectl set-hostname controller [rootcontroller …...
Java 运算符与类型转化
Java 运算符与类型转化 1 算术运算符 Java中的算术运算符主要有(加)、-(减)、*(乘)、/(除)、%(求余),它们都是二元运算符。 2 自增和自减运算…...
《C++ Primer Plus》第18章:探讨 C++ 新标准(2)
移动语义和右值引用 现在介绍本书前面未讨论的主题。C11 支持移动语义,这就提出了一些问题:为何需要移动语义?什么是移动语义?C11 如何支持它?下面首先讨论第一个问题。 为何需要移动语义 先来看 C11 之前的复制过程…...
QML定时器
QML使用Timer使用定时器 Timer 计时器可用于触发操作一次,或以给定的间隔重复触发。 常用属性: interval 设置触发器之间的间隔(以毫秒为单位)。 默认间隔为 1000 毫秒。 repeat 设置重复,为真,则以指定的…...
Firefly开源中文大模型:指令微调、部署与领域适配实战
1. 项目概述:一个专为中文优化的开源大语言模型最近在开源社区里,Firefly(流萤)这个项目引起了我的注意。它不是一个通用框架,而是一个经过精心指令微调的大语言模型系列。简单来说,你可以把它理解为一个“…...
别再只盯着快充了!聊聊交流充电桩(慢充)对电池寿命的友好设计
慢充才是真爱护:揭秘交流充电桩如何用"温柔算法"延长电池寿命 当大多数电动车车主还在为"充电5分钟续航200公里"的快充技术欢呼时,一群电池工程师和资深电车玩家却悄悄把家用充电桩调成了最低电流模式。这不是因为他们时间太多&…...
CANopen通信避坑指南:你的SDO为什么读不到映射变量?从对象字典EDS文件说起
CANopen通信避坑指南:你的SDO为什么读不到映射变量?从对象字典EDS文件说起 调试CANopen通信时,最令人抓狂的瞬间莫过于:从站程序明明能正常读写变量,主站却死活读不到映射值。上周我就遇到一个典型案例——某工业设备厂…...
3步解决Dell G15散热难题:TCC-G15开源散热控制工具完全指南
3步解决Dell G15散热难题:TCC-G15开源散热控制工具完全指南 【免费下载链接】tcc-g15 Thermal Control Center for Dell G15 - open source alternative to AWCC 项目地址: https://gitcode.com/gh_mirrors/tc/tcc-g15 你是否正在为Dell G15笔记本的过热问题…...
Arm编译器嵌入式C/C++库架构与优化实践
1. Arm编译器嵌入式C/C库核心架构解析在嵌入式系统开发中,Arm编译器提供的C/C库是实现高效、可靠应用的基础设施。这些库函数针对Arm架构进行了深度优化,特别是在内存管理、信号处理和浮点运算等关键功能上。让我们先来看看这个库的核心架构设计。Arm编译…...
基于GitHub Actions打造自动化工作流:测试、构建、部署
从手工到自动化的测试交付变革在软件研发流程中,测试从来不是孤立环节。每一次代码提交,都可能触发一轮新的构建、部署与验证。传统模式下,测试人员往往需要等待开发手动打包、手动部署到测试环境,再通过人工触发或定时执行测试脚…...
终局架构:指纹隔离底座 + gRPC分布式调度,重塑千万级拼多多店群RPA集群
大家好,我是林焱,一名专注电商底层业务逻辑与 RPA 自动化架构定制的独立开发者。 在前面的几篇 CSDN 专栏中,我们探讨了如何利用“指纹浏览器底层隔离”解决风控关联问题,如何利用“EDA(事件驱动)”和“CD…...
dotUI设计系统生成器:基于品牌配置一键生成React组件库
1. 项目概述:dotUI,一个为品牌而生的设计系统在当今的Web开发领域,尤其是基于React的生态中,我们常常面临一个两难的选择:是使用现成的UI组件库快速搭建界面,还是投入大量时间从零开始构建一套完全符合品牌…...
FPGA开发实战:从问题定位到系统化解决,构建硬件设计核心能力
1. 项目概述:当FPGA问题来袭,你的第一反应是什么?如果你正在设计一个嵌入式系统,或者在调试一块数字电路板时,遇到了一个用微控制器(MCU)难以解决的时序、并行处理或接口协议问题,你…...
FMCP协议:构建创作者统一文件管理中枢,打破应用孤岛
1. 项目概述:一个为创作者而生的文件管理中枢如果你是一位内容创作者,无论是视频剪辑师、摄影师、平面设计师,还是播客制作人,你的工作流里一定少不了与海量文件打交道。原始素材、工程文件、渲染输出、版本迭代……这些文件散落在…...
