2. 像素数据格式与接口协议:RAW、RGB、YUV、MIPI CSI-2 与 DVP
各位同学,欢迎来到第二章。上一章我们聊了像素处理通路的大框架,今天咱们把镜头拉近,看看这条路上跑的数据到底长什么样,又是怎么从传感器传过来的。
说白了,像素数据就是一堆数字。但这一堆数字怎么组织、怎么解释,直接决定了你后面所有 RTL 模块该怎么写。我见过不少新手,一上来就急着写算法模块,结果连输入数据是 10-bit RAW 还是 8-bit RGB 都没搞清楚,最后仿真波形一塌糊涂。嗯,咱们先把基础打牢。
2.1 三种核心像素格式:RAW、RGB、YUV
图像传感器输出的原始数据,以及后续处理通路里流转的数据,基本就这三种格式。它们各有各的脾气,咱们一个一个说。
2.1.1 RAW 格式:传感器的原生语言
CMOS 图像传感器每个像素点只能感知光的强度,分不清颜色。为了获取彩色信息,传感器表面覆盖了一层彩色滤波阵列(CFA),最常见的就是 Bayer 模式。
Bayer RAW 的特点:
- 每个像素只存一种颜色分量(R、G 或 B)。
- 绿色分量占一半,因为人眼对绿色最敏感。
- 位宽通常是 10-bit、12-bit 甚至 14-bit,精度高。
- 数据量小,是传感器直接输出的格式。
2.1.2 RGB 格式:显示器的通用语言
RGB 格式大家最熟悉,每个像素由 R、G、B 三个分量组成。但这里有个坑——色彩空间。
sRGB、Adobe RGB、BT.709……不同的色彩空间,同样的 R/G/B 数值,显示出来的颜色是不一样的。做 RTL 设计时,你不需要关心色彩空间的数学细节,但必须知道你的模块输入输出是哪个色彩空间,否则级联起来颜色就乱了。
常见的 RGB 数据排布方式:
| 格式 | 说明 | 典型位宽 |
|---|---|---|
| RGB888 | 每个分量 8-bit,共 24-bit | 24-bit |
| RGB565 | R:5-bit, G:6-bit, B:5-bit,共 16-bit | 16-bit |
| RGB666 | 每个分量 6-bit,共 18-bit | 18-bit |
2.1.3 YUV 格式:视频压缩的基石
YUV 把亮度(Y)和色度(U/V)分开。人眼对亮度变化敏感,对颜色变化不敏感,所以可以降低色度的采样率来压缩数据量。
常见的 YUV 采样格式:
- YUV444:每个像素都有完整的 Y、U、V,数据量最大。
- YUV422:每两个像素共享一组 U/V,水平方向色度减半。
- YUV420:每四个像素共享一组 U/V,水平和垂直方向色度都减半。这是视频编码最常用的格式。
2.2 接口协议基础:MIPI CSI-2 与 DVP
传感器把数据准备好了,怎么传给我们的芯片?目前主流就两种:DVP 和 MIPI CSI-2。
2.2.1 DVP 接口:经典的并行接口
DVP(Digital Video Port)是传统的并行接口,信号线比较多,但逻辑简单。
DVP 的关键信号:
- PCLK:像素时钟,每个时钟沿传输一个像素数据。
- HSYNC:行同步信号,表示一行数据的开始。
- VSYNC:场同步信号,表示一帧数据的开始。
- DATA[7:0] 或 DATA[9:0]:并行数据总线。
- PCLK:像素时钟,每个时钟沿传输一个像素数据。
DVP 的时序很简单:VSYNC 有效后,HSYNC 开始脉冲,然后每个 PCLK 输出一个像素。但 DVP 的缺点是信号线太多,频率上不去,一般用在低分辨率或低帧率的场景。
2.2.2 MIPI CSI-2 接口:高速串行接口
MIPI CSI-2 是目前智能手机和高端摄像头的主流接口。它使用差分信号对(D-PHY)进行高速串行传输,信号线少,速率高。
MIPI CSI-2 的层次结构:
- PHY 层(D-PHY):负责物理信号的传输,包括时钟 Lane 和数据 Lane。
- Lane 管理层:负责将数据分发到多个 Lane 上,以及从多个 Lane 上合并数据。
- 协议层:定义数据包格式,包括长包(像素数据)和短包(同步信息)。
- 应用层:定义像素数据的格式(RAW8、RAW10、YUV422 等)。
2.3 像素时钟与行场同步信号
不管用 DVP 还是 MIPI,最终在芯片内部,我们都需要把串行数据恢复成并行的像素流,并且生成对应的同步信号。
像素时钟(PCLK)的计算:
PCLK = 分辨率宽度 × 分辨率高度 × 帧率 × (1 + 消隐区比例)
举个例子:1080p(1920×1080)、60fps、消隐区约 20%,那么 PCLK 大约是:
1920 × 1080 × 60 × 1.2 ≈ 149.3 MHz
这个频率决定了你的 RTL 逻辑能不能跑得动。如果 PCLK 太高,就需要考虑多路并行处理或者流水线插入。
行场同步信号的生成:
在 RTL 里,我们通常用计数器来模拟行场同步。行计数器从 0 数到一行像素数减 1,场计数器从 0 数到一帧行数减 1。HSYNC 和 VSYNC 的脉冲宽度和位置,由具体的传感器规格决定。
// 简单的行场同步生成示例
always @(posedge pclk or negedge rst_n) begin
if (!rst_n) begin
h_cnt <= 0;
v_cnt <= 0;
hsync <= 0;
vsync <= 0;
end else begin
// 行计数器
if (h_cnt == H_TOTAL - 1) begin
h_cnt <= 0;
// 场计数器
if (v_cnt == V_TOTAL - 1)
v_cnt <= 0;
else
v_cnt <= v_cnt + 1;
end else begin
h_cnt <= h_cnt + 1;
end
// HSYNC 生成
if (h_cnt >= H_SYNC_START && h_cnt < H_SYNC_END)
hsync <= 1;
else
hsync <= 0;
// VSYNC 生成
if (v_cnt >= V_SYNC_START && v_cnt < V_SYNC_END)
vsync <= 1;
else
vsync <= 0;
end
end
2.4 本章知识结构图
下面这张图总结了本章的核心知识点和它们之间的关系,方便你建立整体认知。