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

相关文章
|
6月前
|
异构计算
FPGA强化(8):HDMI显示器驱动
FPGA入门(8):VGA显示器驱动
55 0
|
芯片 异构计算
FPGA - 基于FPGA的HDMI显示
FPGA - 基于FPGA的HDMI显示
755 0
FPGA - 基于FPGA的HDMI显示
|
8天前
|
算法 数据安全/隐私保护 异构计算
基于FPGA的变步长LMS自适应滤波器verilog实现,包括testbench
### 自适应滤波器仿真与实现简介 本项目基于Vivado2022a实现了变步长LMS自适应滤波器的FPGA设计。通过动态调整步长因子,该滤波器在收敛速度和稳态误差之间取得良好平衡,适用于信道均衡、噪声消除等信号处理应用。Verilog代码展示了关键模块如延迟单元和LMS更新逻辑。仿真结果验证了算法的有效性,具体操作可参考配套视频。
101 74
|
1月前
|
算法 数据安全/隐私保护 异构计算
基于FPGA的16QAM调制+软解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本项目基于FPGA实现了16QAM基带通信系统,包括调制、信道仿真、解调及误码率统计模块。通过Vivado2019.2仿真,设置不同SNR(如8dB、12dB),验证了软解调相较于传统16QAM系统的优越性,误码率显著降低。系统采用Verilog语言编写,详细介绍了16QAM软解调的原理及实现步骤,适用于高性能数据传输场景。
144 69
|
1月前
|
移动开发 算法 数据安全/隐私保护
基于FPGA的QPSK调制+软解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的QPSK调制解调系统,通过Vivado 2019.2进行仿真,展示了在不同信噪比(SNR=1dB, 5dB, 10dB)下的仿真效果。与普通QPSK系统相比,该系统的软解调技术显著降低了误码率。文章还详细阐述了QPSK调制的基本原理、信号采样、判决、解调及软解调的实现过程,并提供了Verilog核心程序代码。
70 26
|
7天前
|
存储 编解码 算法
基于FPGA的直接数字频率合成器verilog实现,包含testbench
本项目基于Vivado 2019.2实现DDS算法,提供完整无水印运行效果预览。DDS(直接数字频率合成器)通过数字信号处理技术生成特定频率和相位的正弦波,核心组件包括相位累加器、正弦查找表和DAC。相位累加器在每个时钟周期累加频率控制字,正弦查找表根据相位值输出幅度,DAC将数字信号转换为模拟电压。项目代码包含详细中文注释及操作视频。
|
2月前
|
算法 异构计算
基于FPGA的4ASK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的4-ASK调制解调系统的算法仿真效果、理论基础及Verilog核心程序。仿真在Vivado2019.2环境下进行,分别测试了SNR为20dB、15dB、10dB时的性能。理论部分概述了4-ASK的工作原理,包括调制、解调过程及其数学模型。Verilog代码实现了4-ASK调制器、加性高斯白噪声(AWGN)信道模拟、解调器及误码率计算模块。
75 8
|
2月前
|
算法 物联网 异构计算
基于FPGA的4FSK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的4FSK调制解调系统的Verilog实现,包括高斯信道模块和误码率统计模块,支持不同SNR设置。系统在Vivado 2019.2上开发,展示了在不同SNR条件下的仿真结果。4FSK调制通过将输入数据转换为四个不同频率的信号来提高频带利用率和抗干扰能力,适用于无线通信和数据传输领域。文中还提供了核心Verilog代码,详细描述了调制、加噪声、解调及误码率计算的过程。
78 11

热门文章

最新文章