FPGA设计——HDMI

简介:

1. 概述

HDMI英文名为High Definition Multimedia Interface,是一种数字化视频、音频接口。 现已

广泛应用于高清数字电视、PC显示器等产品中。

这里我们使用Silicon Image公司的SiI9134作为HDMI发送芯片,支持HDMI 1.3标准。

wKiom1fiI8OROnP9AACkxLnAcSY628.jpg


2. 设计框图

视频源由FPGA内部产生,sii9134的配置通过I2C模块完成。这里以720P60为例完成设计。

wKioL1fiKByROLi7AAAzbEn4dz8962.jpg

3. Sii9134配置

这里将Sii9134配置成YCbCr422输入,RGB444输出模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
void  sii9134_init()
{
     sccb_senddata(0x72,0x05,0x01);   //reset all sections
     sccb_senddata(0x72,0x05,0x00);   //disable reset
 
     sccb_senddata(0x72,0x08,0x37);   //VSYNC and HSYNC, 24bit, rising edge, normal operation
 
     sccb_senddata(0x72,0x0c,0x00);
     sccb_senddata(0x72,0x0d,0x01);
 
     sccb_senddata(0x72,0x4B,0x00);   //Blue
     sccb_senddata(0x72,0x4C,0x00);   //Green
     sccb_senddata(0x72,0x4D,0xff);   //Red
 
     sccb_senddata(0x72,0x82,0x25);   //FPLL*IDCK, enable internal source termination
     sccb_senddata(0x72,0x83,0x19);   //HDMI PLL/2, PLL filter feedback/4, PLL filter front/2
     sccb_senddata(0x72,0x84,0x31);   //50uA, PLL filter post/2
     sccb_senddata(0x72,0x85,0x01);   //HDMI transmitter PLL front/2
 
     sccb_senddata(0x72,0x32,0x04);   //h-blank
     sccb_senddata(0x72,0x33,0x41);   //enable DE, positive polarity, left-blank(370 pixels)
     sccb_senddata(0x72,0x34,0x19);   //v-blank(30 lines)
     sccb_senddata(0x72,0x36,0x00);   //the width of active display
     sccb_senddata(0x72,0x37,0x05);   //the width of active display(1280)
     sccb_senddata(0x72,0x38,0xD0);   //the height of active display
     sccb_senddata(0x72,0x39,0x02);   //the height of active display(720)
 
     sccb_senddata(0x72,0x3E,0x00);
     sccb_senddata(0x72,0x40,0x6e);
     sccb_senddata(0x72,0x41,0x00);
     sccb_senddata(0x72,0x44,0x29);
     sccb_senddata(0x72,0x45,0x00);
     sccb_senddata(0x72,0x46,0x05);
     sccb_senddata(0x72,0x47,0x06);
 
     sccb_senddata(0x72,0x48,0x30);
     sccb_senddata(0x72,0x49,0x00);
     sccb_senddata(0x72,0x4a,0x3c);
 
////////////////////////////////////////////////
     sccb_senddata(0x7a,0x01,0x02);
     sccb_senddata(0x7a,0x02,0x01);
     sccb_senddata(0x7a,0x03,0x00);
     sccb_senddata(0x7a,0x04,0x18);
     sccb_senddata(0x7a,0x05,0x00);
 
     sccb_senddata(0x7a,0x14,0x11);
     sccb_senddata(0x7a,0x1D,0x40);
     sccb_senddata(0x7a,0x21,0x02);
     sccb_senddata(0x7a,0x22,0x2B);
 
     sccb_senddata(0x7a,0x2F,0x01);
 
     sccb_senddata(0x7a,0x40,0x82);
     sccb_senddata(0x7a,0x41,0x02);
     sccb_senddata(0x7a,0x42,0x0d);
     sccb_senddata(0x7a,0x43,0x59);
     sccb_senddata(0x7a,0x44,0x11);
     sccb_senddata(0x7a,0x45,0x28);
     sccb_senddata(0x7a,0x46,0x00);
     sccb_senddata(0x7a,0x47,0x04);
     sccb_senddata(0x7a,0x48,0x00);
     sccb_senddata(0x7a,0x49,0x00);
     sccb_senddata(0x7a,0x4A,0x00);
     sccb_senddata(0x7a,0x4B,0xD1);
     sccb_senddata(0x7a,0x4C,0x02);
     sccb_senddata(0x7a,0x4D,0x00);
     sccb_senddata(0x7a,0x4E,0x00);
     sccb_senddata(0x7a,0x4F,0x01);
     sccb_senddata(0x7a,0x50,0x05);
     sccb_senddata(0x7a,0x51,0x00);
     sccb_senddata(0x7a,0x52,0x00);
 
     sccb_senddata(0x7a,0x80,0x84);
     sccb_senddata(0x7a,0x81,0x01);
     sccb_senddata(0x7a,0x82,0x0a);
     sccb_senddata(0x7a,0x83,0x70);
     sccb_senddata(0x7a,0x84,0x01);
     sccb_senddata(0x7a,0x85,0x00);
     sccb_senddata(0x7a,0x86,0x00);
     sccb_senddata(0x7a,0x87,0x00);
     sccb_senddata(0x7a,0x88,0x00);
     sccb_senddata(0x7a,0x89,0x00);
     sccb_senddata(0x7a,0x8a,0x00);
     sccb_senddata(0x7a,0x8b,0x00);
     sccb_senddata(0x7a,0x8c,0x00);
     sccb_senddata(0x7a,0x8d,0x00);
     sccb_senddata(0x7a,0x3e,0x33);
}


4. FPGA逻辑设计

FPGA逻辑完成视频源生成、HDMI配置、RGB转YCbCr功能。下面表格给出RGB转YC的公式。

Video Format

Formulas

576p

 Y = 0.299R′ + 0.587G′ + 0.114B′
 Cb = –0.172R′ – 0.339G′ + 0.511B′ + 128
 Cr = 0.511R′ – 0.428G′ – 0.083B′ + 128

 
 

480p

240p

720p

 Y = 0.213R′ + 0.715G′ + 0.072B′
 Cb = –0.117R′ – 0.394G′ + 0.511B′ + 128
 Cr = 0.511R′ – 0.464G′ – 0.047B′ + 128

1080p

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
//file name:           hdmi_vid_gen.v
//author:           shugen.yin
//date:             2016.9.21
//function:         hdmi video generation
//log: 
 
module hdmi_vid_gen(
     input clk,   //74.25MHz                         
     input rst_n,
     
     output                              hdmi_clk,
     output                              hdmi_txde,
     output                              hdmi_hs,
     output                              hdmi_vs,
     output [15:0]                         hdmi_data
);
 
 
parameter IMG_HDISP    = 16'd1280;
parameter IMG_VDISP  = 16'd720;
parameter H_OFFSET   = 0;
 
wire pclk;
assign pclk = clk;
 
assign hdmi_clk  = pclk;
assign hdmi_hs  = hsync;
assign hdmi_txde = data_valid;
assign hdmi_vs  = vsync;
assign hdmi_data = data;
 
reg [11:0] vcnt;
reg [15:0] hcnt;
reg vsync;
reg hsync;
reg data_valid;
reg [15:0] data;
reg [7:0] red;
reg [7:0] green;
reg [7:0] blue;
 
 
always @(posedge pclk)
     if (hcnt>=(IMG_HDISP+259))         //720p
         hcnt <= 0;
     else
         hcnt <= hcnt + 1'b1;
     
always @(posedge pclk)
     if (hcnt>=(IMG_HDISP+259))   
         if (vcnt>=(IMG_VDISP+24))
             vcnt <= 0;
         else
             vcnt <= vcnt + 1'b1;
     else
         vcnt <= vcnt;
         
 
always @(posedge pclk)
     if ((hcnt>=IMG_HDISP+H_OFFSET) & (hcnt<=(IMG_HDISP+H_OFFSET+32)) & (vcnt>=0 | (vcnt<IMG_VDISP)))
         hsync <= 1'b1;
     else
         hsync <= 1'b0;
 
always @(posedge pclk)
     if (vcnt<=(IMG_VDISP+2+6) & vcnt>=(IMG_VDISP+2))
         vsync <= 1'b1;
     else
         vsync <= 1'b0;
         
reg cbcr_reg;     
         
always @(posedge pclk)
     if (vsync)
     begin
         data <= 0;
         cbcr_reg <= 0;
         red <= 0;
         green <= 0;
         blue <= 0;
     end
     else  if ((hcnt>=0) & (hcnt<(IMG_HDISP+0)) & (vcnt>=0) & (vcnt<(0+IMG_VDISP/4)))
     begin
         if (~cbcr_reg)
         begin
             data[7:0] <= y;
             data[15:8] <= cb;
         end
         else
         begin
             data[7:0] <= y;
             data[15:8] <= cr;
         end
         cbcr_reg <= ~cbcr_reg;
         red   <= 8'hf0;
         green <= 8'hf0;
         blue  <= 8'h00;
     end
     else  if ((hcnt>=0) & (hcnt<(IMG_HDISP+0)) & (vcnt>=(0+IMG_VDISP/4)) & (vcnt<(0+2*IMG_VDISP/4)))
     begin  
         if (~cbcr_reg)
         begin
             data[7:0] <= y;
             data[15:8] <= cb;
         end
         else
         begin
             data[7:0] <= y;
             data[15:8] <= cr;
         end
         cbcr_reg <= ~cbcr_reg;
         red   <= 8'hf0;
         green <= 8'h00;
         blue  <= 8'h00;
     end
     else  if ((hcnt>=0) & (hcnt<(IMG_HDISP+0)) & (vcnt>=(0+2*IMG_VDISP/4)) & (vcnt<(0+3*IMG_VDISP/4)))
     begin      
         if (~cbcr_reg)
         begin
             data[7:0] <= y;
             data[15:8] <= cb;
         end
         else
         begin
             data[7:0] <= y;
             data[15:8] <= cr;
         end
         cbcr_reg <= ~cbcr_reg;
         red   <= 8'h00;
         green <= 8'hf0;
         blue  <= 8'h00;
     end
     else  if ((hcnt>=0) & (hcnt<(IMG_HDISP+0)) & (vcnt>=(0+3*IMG_VDISP/4)) & (vcnt<(0+IMG_VDISP)))
     begin      
         if (~cbcr_reg)
         begin
             data[7:0] <= y;
             data[15:8] <= cb;
         end
         else
         begin
             data[7:0] <= y;
             data[15:8] <= cr;
         end
         cbcr_reg <= ~cbcr_reg;
         red   <= 8'h00;
         green <= 8'h00;
         blue  <= 8'hf0;
     end
     else
     begin
         data <= 0;
         cbcr_reg <= 0;
         red <= 0;
         green <= 0;
         blue <= 0;
     end
 
 
always @(posedge pclk)
     if (vsync)
         data_valid <= 0;
     else  if ((hcnt>=0) & (hcnt<(IMG_HDISP+0)) & (vcnt>=0) & (vcnt<(0+IMG_VDISP/4)))
         data_valid <= 1;
     else  if ((hcnt>=0) & (hcnt<(IMG_HDISP+0)) & (vcnt>=(0+IMG_VDISP/4)) & (vcnt<(0+2*IMG_VDISP/4)))
         data_valid <= 1;
     else  if ((hcnt>=0) & (hcnt<(IMG_HDISP+0)) & (vcnt>=(0+2*IMG_VDISP/4)) & (vcnt<(0+3*IMG_VDISP/4)))
         data_valid <= 1;
     else  if ((hcnt>=0) & (hcnt<(IMG_HDISP+0)) & (vcnt>=(0+3*IMG_VDISP/4)) & (vcnt<(0+IMG_VDISP)))
         data_valid <= 1;
     else
         data_valid <= 0;      
 
 
wire [7:0] y;    
wire [7:0] cb;
wire [7:0] cr;
 
rgb2ycbcr rgb2ycbcr_inst
(
     .clk(pclk) ,    // input  clk_sig
     .rst_n(rst_n) ,     // input  rst_n_sig
     .red(red) ,     // input [7:0] red_sig
     .green(green) ,     // input [7:0] green_sig
     .blue(blue) ,   // input [7:0] blue_sig
     .y(y) ,     // output [7:0] y_sig
     .cb(cb) ,   // output [7:0] cb_sig
     .cr(cr)     // output [7:0] cr_sig
);         
         
 
endmodule


5. 最终结果

在显示器上显示1280*720@60帧的彩条视频。

wKiom1fiLEvjrt-WAA-tY0buEtA625.jpg


本文转自 shugenyin 51CTO博客,原文链接:http://blog.51cto.com/shugenyin/1854938

相关文章
|
异构计算
FPGA强化(8):HDMI显示器驱动
FPGA入门(8):VGA显示器驱动
201 0
|
芯片 异构计算
FPGA - 基于FPGA的HDMI显示
FPGA - 基于FPGA的HDMI显示
1320 0
FPGA - 基于FPGA的HDMI显示
|
算法 数据安全/隐私保护 异构计算
基于FPGA的变步长LMS自适应滤波器verilog实现,包括testbench
### 自适应滤波器仿真与实现简介 本项目基于Vivado2022a实现了变步长LMS自适应滤波器的FPGA设计。通过动态调整步长因子,该滤波器在收敛速度和稳态误差之间取得良好平衡,适用于信道均衡、噪声消除等信号处理应用。Verilog代码展示了关键模块如延迟单元和LMS更新逻辑。仿真结果验证了算法的有效性,具体操作可参考配套视频。
461 74
|
10月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于FPGA的SNN脉冲神经网络之LIF神经元verilog实现,包含testbench
本项目展示了 LIF(Leaky Integrate-and-Fire)神经元算法的实现与应用,含无水印运行效果预览。基于 Vivado2019.2 开发,完整代码配有中文注释及操作视频。LIF 模型模拟生物神经元特性,通过积分输入信号并判断膜电位是否达阈值产生脉冲,相较于 Hodgkin-Huxley 模型更简化,适合大规模神经网络模拟。核心程序片段示例,助您快速上手。
|
11月前
|
算法 数据安全/隐私保护 异构计算
基于LSB最低有效位的音频水印嵌入提取算法FPGA实现,包含testbench和MATLAB对比
本项目展示了一种基于FPGA的音频水印算法,采用LSB(最低有效位)技术实现版权保护与数据追踪功能。使用Vivado2019.2和Matlab2022a开发,完整代码含中文注释及操作视频。算法通过修改音频采样点的最低有效位嵌入水印,人耳难以察觉变化。然而,面对滤波或压缩等攻击时,水印提取可能受影响。该项目运行效果无水印干扰,适合实时应用场景,核心逻辑简单高效,时间复杂度低。
|
算法 数据安全/隐私保护 异构计算
基于FPGA的16QAM调制+软解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本项目基于FPGA实现了16QAM基带通信系统,包括调制、信道仿真、解调及误码率统计模块。通过Vivado2019.2仿真,设置不同SNR(如8dB、12dB),验证了软解调相较于传统16QAM系统的优越性,误码率显著降低。系统采用Verilog语言编写,详细介绍了16QAM软解调的原理及实现步骤,适用于高性能数据传输场景。
601 69
|
11月前
|
算法 数据安全/隐私保护 异构计算
基于FPGA的2ASK+帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可设置SNR
本内容展示了基于Vivado2019.2的算法仿真效果,包括设置不同信噪比(SNR=8db和20db)下的结果及整体波形。同时,详细介绍了2ASK调制解调技术的原理与实现,即通过改变载波振幅传输二进制信号,并提供数学公式支持。此外,还涉及帧同步理论,用于确定数据帧起始位置。最后,给出了Verilog核心程序代码,实现了2ASK解调与帧同步功能,结合DDS模块生成载波信号,完成信号处理流程。
212 0
|
11月前
|
编解码 算法 数据安全/隐私保护
基于FPGA的信号DM编解码实现,包含testbench和matlab对比仿真
本项目展示了DM编解码算法的实现与测试结果。FPGA测试结果显示为T1,Matlab仿真结果为T2。使用软件版本为Matlab 2022a和Vivado 2019.2。核心程序包含详细中文注释和操作视频。DM编解码通过比较信号样本差值进行编码,适用于音频等低频信号处理。硬件结构包括编码器(采样器、减法器、比较器)和解码器(解码器、积分器)。

热门文章

最新文章