HDMI20协议解析_Audio_Sample
1.版本说明
| 日期 | 作者 | 版本说明 | 
|---|---|---|
| 202409XX | 风释雪 | 初始版本 | 
2.概述
当通过HDMI传输音频信号时,Audio_Sample是必须要传输的数据包之一;
 通过前端硬件或软件收到PCM原始音频数据后,需要通过Audio_Sample packet发送给sink端,
 sink端收到后,结合协议解析出原始PCM音频数据,用来播放声音;
 同时(重点),该协议还会按照IEC-60958打包传输通道状态信息,该信息包含音频采样位宽,
 音频采样率,通道数量等信息,非常重要!!
3.目标
FPGA 实现 HDMI2.0 TX/RX功能,生成或解析对应的Audio Sample数据包,用于传输双通道立体声 
4.协议解析
-  协议分类 
-   
-  协议格式 
-   
5.参数分析
-  layout 
-   
-  通常 HDMI只传输2个通道,因此 layout = 0; 
-  sample_present.sp[3:0] : 有效通道使能bit,当传输2个通道时,4’b0001 
-  sample_flat.sp[3:0] : 固定 4’b0000 
-   
-  B[3:0] : 音频帧起始状态,根据IEC-60958, 每一帧包含192个subframe,计数器0-191, 当等于0时,B[x] = 1 
B.X [4 fields, 1 bit each] B.X =1 if Subpacket X contains the first frame in a 192
frame IEC 60958 Channel Status block; B.X = 0 otherwise
备注:需要先理解 IEC-60958
- L/R 左右声道数据
- P/C/U/V
    P : 校验
    U : 用户数据,固定 0
    V : 固定 0
    C : 状态信息bit,参考IEC-60958,该信息包含音频采样位宽,音频采样率,通道数量等信息,非常重要!!
6.IEC-60958
-  参考 https://blog.csdn.net/luckywang1103/article/details/88886810 (感谢分享) 
-  参考 https://www.cnblogs.com/fellow1988/p/6445489.html (感谢分享) 
-   
-   
-  总结 : 
    一个block,共 192 Frames, 一个Frames等于2个(左+右)subframe,每个subframe代表一个声道的音频数据+V/U/C/P+其他数据(不关心)
    因此, 一个block,可以传输 192个左右声道数据,加192bit左右通道信息数据
7.C 通道信息
- 每个声道的通道信息共 192 bit, 每个audio sample packet 只传输1个bit,共需要192次才能传输完;
- C 通道信息包含 消费级 和 专业级, 日常使用为消费级;
 
status[0] : PRO = 1'b0 消费级
status[1] : AUDIO = 1'b0
status[2] : Copy = 1'b0
status[5:3] : Emphasis = 3'b000
status[7:6] : Mode = 2'b00
status[15:8] : Category Code = 8'b10000000
status[19:16] : Source Num = 4'b0000
status[23:20] : Channel Num = 4'b0001 (Left) 4'b0010 (Right)
status[27:24] : FS = 4'b0000(44.1K) 4'b1000(88.2K) 4'b1100(176.4K) 4'b0010 (48K) 4'b1010 (96K) 4'b1110 (192K)
status[29:28] : Clock Acc = 2'b00
status[32] : Word Max = 1'b0  Max word length is 20 bits , Word Max = 1'b1  Max word length is 24 bits,
status[35:33] :  Word Length = IF(Word Max == 1'b0) : 3'b001(16bits), 3'b010(18bits) 3'b100(19bits) 3'b101(20bits) 3'b110(17bits)
-----------------Word Length = IF(Word Max == 1'b1) : 3'b001(20bits), 3'b010(22bits) 3'b100(23bits) 3'b101(24bits) 3'b110(21bits)
8.P 校验
    P = ^ {C, U, V, DATA[23:0]}
9.软件实现
// ch1
wire           [24                      -1 : 0] ch1_data                    ;
wire                                            ch1_c                       ; // 0 not use 1 use
wire                                            ch1_u                       ; // 0 not use 1 use
wire                                            ch1_v                       ; // 0 valid 1 no valid
wire                                            ch1_p                       ;
// ch2
wire           [24                      -1 : 0] ch2_data                    ;
wire                                            ch2_c                       ; // 0 not use 1 use
wire                                            ch2_u                       ; // 0 not use 1 use
wire                                            ch2_v                       ; // 0 valid 1 no valid
wire                                            ch2_p                       ;
reg            [192                    - 1 : 0] status_l                    = 0;
reg            [192                    - 1 : 0] status_r                    = 0;
reg            [8                      - 1 : 0] cnt                         = 0;
always @(posedge clk) begin
    status_l[0]      <= 1'b0;
    status_l[1]      <= 1'b0;
    status_l[2]      <= 1'b0;
    status_l[5:3]    <= 3'b000;
    status_l[7:6]    <= 2'b00;
    status_l[15:8]   <= 8'b10000000;
    status_l[19:16]  <= 4'b0000;
    status_l[23:20]  <= 4'b0001;
    status_l[27:24]  <= (aud_fs == `ARG_AUD_44_1KFS) ? 4'b0000 : (aud_fs == `ARG_AUD_48KFS) ? 4'b0010 : 4'b0010 /* (48K) */;
    status_l[29:28]  <= 2'b00;
    status_l[31:30]  <= 2'b00;
    status_l[32]     <= 1'd1;
    status_l[35:33]  <= (aud_bit == `ARG_AUD_16BIT) ? 3'b001 : (aud_bit == `ARG_AUD_24BIT) ? 3'b101 : 3'b101 /* (24bits) */;
    status_l[191:36] <= 156'd0;
    status_r[0]      <= 1'b0;
    status_r[1]      <= 1'b0;
    status_r[2]      <= 1'b0;
    status_r[5:3]    <= 3'b000;
    status_r[7:6]    <= 2'b00;
    status_r[15:8]   <= 8'b10000000;
    status_r[19:16]  <= 4'b0000;
    status_r[23:20]  <= 4'b0010;
    status_r[27:24]  <= (aud_fs == `ARG_AUD_44_1KFS) ? 4'b0000 : (aud_fs == `ARG_AUD_48KFS) ? 4'b0010 : 4'b0010 /* (48K) */;
    status_r[29:28]  <= 2'b00;
    status_r[31:30]  <= 2'b00;
    status_r[32]     <= 1'd1;
    status_r[35:33]  <= (aud_bit == `ARG_AUD_16BIT) ? 3'b001 : (aud_bit == `ARG_AUD_24BIT) ? 3'b101 : 3'b101 /* (24bits) */;
    status_r[191:36] <= 156'd0;
end
assign {ch2_data, ch1_data} = aud_data;
assign ch1_c = status_l[cnt];
assign ch1_u = 1'd0;
assign ch1_v = 1'd0;
assign ch1_p = (^ch1_data[23:0]) ^ ch1_c ^ ch1_u ^ ch1_v;
assign ch2_c = status_r[cnt];
assign ch2_u = 1'd0;
assign ch2_v = 1'd0;
assign ch2_p = (^ch2_data[23:0]) ^ ch2_c ^ ch2_u ^ ch2_v;
5.参考文档
- EIA-CEA-861-D
- HDMI 1.4(1.4b/2.0)
- IEC-60958-1
- IEC-60958-3-2003





















