2. HDMI 2.0 时钟通道与数据通道映射
任务说明
本案例完成HDMI 2.0源端(Source)在发送TMDS符号流之前,将像素数据、控制数据与辅助数据正确映射到4个通道(3个数据通道+1个时钟通道)的字节级封装逻辑。目标输入为24位RGB像素流与视频时序控制信号,输出为4路并行TMDS字符流(每通道10 bit),并给出通道分配与字符编码前的数据布局验证方法。
HDMI 2.0 通道映射规则
HDMI 2.0使用3个TMDS数据通道(Channel 0/1/2)和一个独立的时钟通道。像素数据在3个通道间按字节交错分配:24位像素的R/G/B各8位分别送入Channel 2/1/0(即Channel 0承载蓝色分量,Channel 1承载绿色,Channel 2承载红色)。视频消隐期传输的控制数据(HSYNC、VSYNC、CTL0~CTL3)固定映射到Channel 0/1/2的特定引脚。辅助数据(Audio、InfoFrame等)在消隐期通过数据岛(Data Island)周期以4位半字节(nibble)形式在3个通道上并行传输。时钟通道独立传输像素时钟,不参与数据映射。
核心实现
// hdmi20_channel_map.v
`timescale 1ns/1ps
module hdmi20_channel_map #(
parameter PIXEL_WIDTH = 24 // 24-bit RGB888
)(
input wire clk_pixel, // 像素时钟(= TMDS时钟)
input wire rst_n,
// 视频像素流输入
input wire [PIXEL_WIDTH-1:0] pixel_rgb, // {R[7:0], G[7:0], B[7:0]}
input wire video_active, // 有效像素区(DE=1)
// 控制信号输入(消隐期有效)
input wire hsync,
input wire vsync,
input wire [3:0] ctl, // {CTL3,CTL2,CTL1,CTL0}
// 辅助数据输入(Data Island周期)
input wire aux_valid, // 辅助数据有效
input wire [3:0] aux_nibble_ch0, // Channel 0 半字节
input wire [3:0] aux_nibble_ch1, // Channel 1 半字节
input wire [3:0] aux_nibble_ch2, // Channel 2 半字节
// 输出:4通道并行数据(送入TMDS编码器前)
output reg [7:0] ch0_data, // Channel 0 数据字节
output reg [7:0] ch1_data, // Channel 1 数据字节
output reg [7:0] ch2_data, // Channel 2 数据字节
output reg [1:0] ch0_ctl, // Channel 0 控制位 {VSYNC,HSYNC}
output reg [1:0] ch1_ctl, // Channel 1 控制位 {CTL1,CTL0}
output reg [1:0] ch2_ctl, // Channel 2 控制位 {CTL3,CTL2}
output reg ch0_is_aux, // 1=当前周期为辅助数据
output reg ch1_is_aux,
output reg ch2_is_aux
);
// 像素字节拆分
wire [7:0] r_byte = pixel_rgb[23:16];
wire [7:0] g_byte = pixel_rgb[15:8];
wire [7:0] b_byte = pixel_rgb[7:0];
always @(posedge clk_pixel or negedge rst_n) begin
if (!rst_n) begin
ch0_data <= 8'd0;
ch1_data <= 8'd0;
ch2_data <= 8'd0;
ch0_ctl <= 2'b00;
ch1_ctl <= 2'b00;
ch2_ctl <= 2'b00;
ch0_is_aux <= 1'b0;
ch1_is_aux <= 1'b0;
ch2_is_aux <= 1'b0;
end else begin
// 默认清零辅助标志
ch0_is_aux <= 1'b0;
ch1_is_aux <= 1'b0;
ch2_is_aux <= 1'b0;
if (video_active) begin
// 有效像素区:RGB各8位映射到三个通道
ch0_data <= b_byte; // Channel 0 ← Blue
ch1_data <= g_byte; // Channel 1 ← Green
ch2_data <= r_byte; // Channel 2 ← Red
// 像素期控制位固定为2'b00
ch0_ctl <= 2'b00;
ch1_ctl <= 2'b00;
ch2_ctl <= 2'b00;
end else if (aux_valid) begin
// Data Island周期:传输辅助数据半字节
ch0_data <= {4'd0, aux_nibble_ch0}; // 高4位填充0
ch1_data <= {4'd0, aux_nibble_ch1};
ch2_data <= {4'd0, aux_nibble_ch2};
ch0_ctl <= 2'b00;
ch1_ctl <= 2'b00;
ch2_ctl <= 2'b00;
ch0_is_aux <= 1'b1;
ch1_is_aux <= 1'b1;
ch2_is_aux <= 1'b1;
end else begin
// 控制周期:传输HSYNC/VSYNC/CTL
ch0_data <= 8'd0;
ch1_data <= 8'd0;
ch2_data <= 8'd0;
ch0_ctl <= {vsync, hsync}; // Channel 0: VSYNC,HSYNC
ch1_ctl <= ctl[1:0]; // Channel 1: CTL1,CTL0
ch2_ctl <= ctl[3:2]; // Channel 2: CTL3,CTL2
end
end
end
endmodule
通道映射结构
验证方法
编写testbench驱动上述模块:在像素时钟的连续周期内,依次施加像素数据(如RGB=0x336699)、控制信号(HSYNC=1, VSYNC=0, CTL=4'b1010)与辅助数据(nibble=4'h5,4'hA,4'h3),观察各通道输出。判定标准:
- 当
video_active=1时,ch0_data=0x99(蓝色分量)、ch1_data=0x66(绿色)、ch2_data=0x33(红色),且三个_ctl均为2'b00; - 当
video_active=0且aux_valid=0时,ch0_ctl={vsync,hsync}=2'b01,ch1_ctl=2'b10(CTL[1:0]),ch2_ctl=2'b10(CTL[3:2]); - 当
aux_valid=1时,三个通道的_is_aux信号拉高,且数据字节低4位分别等于输入的半字节值。
上述映射结果可直接作为后续TMDS编码器(8b/10b)的输入,无需额外转换。