| 1概述 上面的课程,我们完成了对TMDS三通道数据的拆分,成功提取出数据岛部分的4bit数据,本讲我们需要将4bit的island data数据恢复成BCH块的形式,方便我们对原始数据的恢复。2原理部分   
 关于BCH块编解码原理的介绍,我们前面的课程已经讲解过了,本章节我们要做的就是逆向恢复出BCH block数据。首先我们通过串并转换恢复出32bit的Channel 0[0:3] ~ Channel 2[0:3]数据。然后对Channel 0~Channel 2的数据进行拆分重组。3代码部分 3.1data_island_bch_assembler.v模块
 该模块为HDMI数据岛周期BCH编码组装器,负责将HDMI控制周期的并行数据流重组为符合BCH纠错编码规范的结构化数据块。其通过三路输入通道接收TMDS编码后的4位数据岛信息(含同步信号、音频及辅助数据),利用多级移位寄存器对数据进行位序列重组,最终输出符合HDMI 1.4b规范(CTA-861标准)的5个BCH编码块(4×64位+1×32位)。同时模块集成同步信号提取功能,可分离垂直/水平同步信号,为后续BCH校验及TMDS传输提供标准化的数据封装接口。 3.2hdmi_audio_packet_decoder.v模块复制代码`timescale 1ns / 1ps  
//////////////////////////////////////////////////////////////////////////////////  
// 模块名称:HDMI数据岛BCH编码组装器  
// 功能描述:将HDMI数据岛周期的并行数据重组为BCH纠错码块结构  
// 关键特性:  
//   - 支持HDMI 1.4b规范的数据岛协议  
//   - 生成5个BCH块(4个64bit + 1个32bit)  
//   - 集成数据有效性校验机制  
//////////////////////////////////////////////////////////////////////////////////  
module data_island_bch_assembler(  
input  wire         I_pixel_clk,    // 像素时钟(与TMDS字符速率同步)  
input  wire         I_reste_n,      // 异步复位(低有效,注意命名应为reset_n)  
input  wire [3:0]   I_island_data_ch0,  // 数据岛通道0输入(含VSYNC/HSYNC)  
input  wire [3:0]   I_island_data_ch1,  // 数据岛通道1输入(音频/辅助数据)  
input  wire [3:0]   I_island_data_ch2,  // 数据岛通道2输入(音频/辅助数据)  
input  wire         I_island_data_vaild, // 数据有效标志(高电平有效)  
// BCH块输出(符合HDMI规范第6.4节结构)  
output reg [63:0]   O_BCH_block_0 ,  // BCH块0(交叉组合通道1&2数据)  
output reg [63:0]   O_BCH_block_1 ,  // BCH块1(交叉组合通道1&2数据)  
output reg [63:0]   O_BCH_block_2 ,  // BCH块2(交叉组合通道1&2数据)  
output reg [63:0]   O_BCH_block_3 ,  // BCH块3(交叉组合通道1&2数据)  
output reg [31:0]   O_BCH_block_4 ,  // BCH块4(直接来自通道0数据)  
output reg          O_block_data_vaild, // BCH块有效标志  
output reg          O_vsync,        // 垂直同步输出  
output reg          O_hsync         // 水平同步输出  
);
// 控制信号寄存器组  
reg [4:0]  r_block_data_cunt;       // BCH块数据计数器(注意命名应为count)  
reg        r_block_data_vaild;      // 块数据有效中间信号  
reg        r_island_data_ch0_d0;    // 通道0数据延迟寄存器(第0级)  
reg        r_island_data_ch0_d1;    // 通道0数据延迟寄存器(第1级)  
reg        r_island_data_vaild;     // 有效信号延迟寄存器  
reg [31:0] r_island_data_ch0_d2;  // 通道0数据位2的移位寄存器 
// 通道1数据移位寄存器组(4bit输入展开为32bit)  
reg [31:0] r_island_data_ch1_d0;  // 通道1数据位0的移位寄存器  
reg [31:0] r_island_data_ch1_d1;  // 通道1数据位1的移位寄存器   
reg [31:0] r_island_data_ch1_d2;  // 通道1数据位2的移位寄存器  
reg [31:0] r_island_data_ch1_d3;  // 通道1数据位3的移位寄存器  
// 通道2数据移位寄存器组(同通道1结构)  
reg [31:0] r_island_data_ch2_d0;  // 通道2数据位0移位寄存器  
reg [31:0] r_island_data_ch2_d1;  // 通道2数据位1移位寄存器  
reg [31:0] r_island_data_ch2_d2;  // 通道2数据位2移位寄存器  
reg [31:0] r_island_data_ch2_d3;  // 通道2数据位3移位寄存器
// BCH块数据计数器(每个块32个有效数据)  
always @(posedge I_pixel_clk or negedge I_reste_n) begin  
    if (!I_reste_n) begin  
        r_block_data_cunt <= 'b0;  // 复位清零  
    end  
    else begin   
        if (I_island_data_vaild && r_block_data_cunt <= 5'h1E)  
            r_block_data_cunt <= r_block_data_cunt + 1;  // 有效数据计数  
        else   
            r_block_data_cunt <= 'b0;  // 计数器归零  
    end  
end 
// BCH块有效信号生成(计数满30周期触发)  
always @(posedge I_pixel_clk or negedge I_reste_n) begin  
    if (!I_reste_n)   
        r_block_data_vaild <= 'b0;  
    else if (r_block_data_cunt == 5'h1E)  // 达到30计数时  
        r_block_data_vaild <= 1;          // 置位有效信号  
    else   
        r_block_data_vaild <= 'b0;  
end 
// 有效信号延迟一拍  
always @(posedge I_pixel_clk or negedge I_reste_n) begin  
    if (!I_reste_n)   
        r_island_data_vaild <= 'b0;  
    else   
        r_island_data_vaild <= r_block_data_vaild;  // 同步时序  
end
// 输出有效信号生成  
always @(posedge I_pixel_clk) begin  
    if (!I_reste_n)   
        O_block_data_vaild <= 'b0;  
    else   
        O_block_data_vaild <= r_island_data_vaild;  // 最终有效信号  
end 
// 数据移位寄存器处理(通道1&2数据重组)  
always @(posedge I_pixel_clk or negedge I_reste_n) begin  
    if (!I_reste_n) begin  // 复位初始化  
        r_island_data_ch0_d2 <= 'b0;  
        r_island_data_ch1_d0 <= 'b0;  
        r_island_data_ch1_d1 <= 'b0;  
        r_island_data_ch1_d2 <= 'b0;  
        r_island_data_ch1_d3 <= 'b0;  
        r_island_data_ch2_d0 <= 'b0;  
        r_island_data_ch2_d1 <= 'b0;  
        r_island_data_ch2_d2 <= 'b0;  
        r_island_data_ch2_d3 <= 'b0;  
    end  
    else if (I_island_data_vaild) begin  // 有效数据周期  
        // 通道0数据移位(bit2)  
        r_island_data_ch0_d2 <= {I_island_data_ch0[2],r_island_data_ch0_d2[31:1]};  
        // 通道1四bit数据分别移位  
        r_island_data_ch1_d0 <= {I_island_data_ch1[0],r_island_data_ch1_d0[31:1]};  
        r_island_data_ch1_d1 <= {I_island_data_ch1[1],r_island_data_ch1_d1[31:1]};  
        r_island_data_ch1_d2 <= {I_island_data_ch1[2],r_island_data_ch1_d2[31:1]};  
        r_island_data_ch1_d3 <= {I_island_data_ch1[3],r_island_data_ch1_d3[31:1]};  
        // 通道2四bit数据分别移位(同通道1)  
        r_island_data_ch2_d0 <= {I_island_data_ch2[0],r_island_data_ch2_d0[31:1]};  
        r_island_data_ch2_d1 <= {I_island_data_ch2[1],r_island_data_ch2_d1[31:1]};  
        r_island_data_ch2_d2 <= {I_island_data_ch2[2],r_island_data_ch2_d2[31:1]};  
        r_island_data_ch2_d3 <= {I_island_data_ch2[3],r_island_data_ch2_d3[31:1]};  
    end  
    else begin  // 非有效周期清零  
        r_island_data_ch0_d2 <= 'b0;  
        r_island_data_ch1_d0 <= 'b0;  
        r_island_data_ch1_d1 <= 'b0;  
        r_island_data_ch1_d2 <= 'b0;  
        r_island_data_ch1_d3 <= 'b0;  
        r_island_data_ch2_d0 <= 'b0;  
        r_island_data_ch2_d1 <= 'b0;  
        r_island_data_ch2_d2 <= 'b0;  
        r_island_data_ch2_d3 <= 'b0;  
    end  
end
// 通道0 bit0数据延迟链(生成HSYNC)  
always @(posedge I_pixel_clk or negedge I_reste_n) begin  
    if (!I_reste_n) begin  
        r_island_data_ch0_d0 <= 'b0;  
    end  
    else   
        r_island_data_ch0_d0 <= I_island_data_ch0[0];  // 同步输入数据  
end
// HSYNC信号输出  
always @(posedge I_pixel_clk or negedge I_reste_n) begin  
    if (!I_reste_n) begin  
        O_hsync <= 'b0;  
    end  
    else   
        O_hsync <= r_island_data_ch0_d0;  // 直接输出延迟后的信号  
end 
// 通道0 bit1数据延迟链(生成VSYNC)  
always @(posedge I_pixel_clk or negedge I_reste_n) begin  
    if (!I_reste_n) begin  
        r_island_data_ch0_d1 <= 'b0;  
    end  
    else   
        r_island_data_ch0_d1 <= I_island_data_ch0[1];  // 同步输入数据  
end 
// VSYNC信号输出  
always @(posedge I_pixel_clk or negedge I_reste_n) begin  
    if (!I_reste_n) begin  
        O_vsync <= 'b0;  
    end  
    else   
        O_vsync <= r_island_data_ch0_d1;  // 直接输出延迟后的信号  
end
// BCH块0组装逻辑(通道1&2数据交叉排列)
always @(posedge I_pixel_clk or negedge I_reste_n) begin
    if (!I_reste_n) begin
        O_BCH_block_0 <= 'b0;
    end
    else  begin
        if (r_island_data_vaild) 
            O_BCH_block_0 <= {r_island_data_ch2_d0[31],r_island_data_ch1_d0[31],r_island_data_ch2_d0[30],r_island_data_ch1_d0[30],
                              r_island_data_ch2_d0[29],r_island_data_ch1_d0[29],r_island_data_ch2_d0[28],r_island_data_ch1_d0[28],   
                              r_island_data_ch2_d0[27],r_island_data_ch1_d0[27],r_island_data_ch2_d0[26],r_island_data_ch1_d0[26], 
                              r_island_data_ch2_d0[25],r_island_data_ch1_d0[25],r_island_data_ch2_d0[24],r_island_data_ch1_d0[24],
                              r_island_data_ch2_d0[23],r_island_data_ch1_d0[23],r_island_data_ch2_d0[22],r_island_data_ch1_d0[22],                        
                              r_island_data_ch2_d0[21],r_island_data_ch1_d0[21],r_island_data_ch2_d0[20],r_island_data_ch1_d0[20],
                              r_island_data_ch2_d0[19],r_island_data_ch1_d0[19],r_island_data_ch2_d0[18],r_island_data_ch1_d0[18],
                              r_island_data_ch2_d0[17],r_island_data_ch1_d0[17],r_island_data_ch2_d0[16],r_island_data_ch1_d0[16],
                              r_island_data_ch2_d0[15],r_island_data_ch1_d0[15],r_island_data_ch2_d0[14],r_island_data_ch1_d0[14],
                              r_island_data_ch2_d0[13],r_island_data_ch1_d0[13],r_island_data_ch2_d0[12],r_island_data_ch1_d0[12],
                              r_island_data_ch2_d0[11],r_island_data_ch1_d0[11],r_island_data_ch2_d0[10],r_island_data_ch1_d0[10],
                              r_island_data_ch2_d0[9 ],r_island_data_ch1_d0[9 ],r_island_data_ch2_d0[8 ],r_island_data_ch1_d0[8 ],
                              r_island_data_ch2_d0[7 ],r_island_data_ch1_d0[7 ],r_island_data_ch2_d0[6 ],r_island_data_ch1_d0[6 ],
                              r_island_data_ch2_d0[5 ],r_island_data_ch1_d0[5 ],r_island_data_ch2_d0[4 ],r_island_data_ch1_d0[4 ],
                              r_island_data_ch2_d0[3 ],r_island_data_ch1_d0[3 ],r_island_data_ch2_d0[2 ],r_island_data_ch1_d0[2 ],
                              r_island_data_ch2_d0[1 ],r_island_data_ch1_d0[1 ],r_island_data_ch2_d0[0 ],r_island_data_ch1_d0[0 ]};
        else  O_BCH_block_0 <= 'b0;
    end
        
end
// BCH块1组装逻辑(通道1&2数据交叉排列)
always @(posedge I_pixel_clk or negedge I_reste_n) begin
    if (!I_reste_n) begin
        O_BCH_block_1 <= 'b0;
    end
    else begin
        if (r_island_data_vaild) 
            O_BCH_block_1 <= {r_island_data_ch2_d1[31],r_island_data_ch1_d1[31],r_island_data_ch2_d1[30],r_island_data_ch1_d1[30],
                              r_island_data_ch2_d1[29],r_island_data_ch1_d1[29],r_island_data_ch2_d1[28],r_island_data_ch1_d1[28], 
                              r_island_data_ch2_d1[27],r_island_data_ch1_d1[27],r_island_data_ch2_d1[26],r_island_data_ch1_d1[26], 
                              r_island_data_ch2_d1[25],r_island_data_ch1_d1[25],r_island_data_ch2_d1[24],r_island_data_ch1_d1[24],
                              r_island_data_ch2_d1[23],r_island_data_ch1_d1[23],r_island_data_ch2_d1[22],r_island_data_ch1_d1[22], 
                              r_island_data_ch2_d1[21],r_island_data_ch1_d1[21],r_island_data_ch2_d1[20],r_island_data_ch1_d1[20],
                              r_island_data_ch2_d1[19],r_island_data_ch1_d1[19],r_island_data_ch2_d1[18],r_island_data_ch1_d1[18],
                              r_island_data_ch2_d1[17],r_island_data_ch1_d1[17],r_island_data_ch2_d1[16],r_island_data_ch1_d1[16],
                              r_island_data_ch2_d1[15],r_island_data_ch1_d1[15],r_island_data_ch2_d1[14],r_island_data_ch1_d1[14],
                              r_island_data_ch2_d1[13],r_island_data_ch1_d1[13],r_island_data_ch2_d1[12],r_island_data_ch1_d1[12],
                              r_island_data_ch2_d1[11],r_island_data_ch1_d1[11],r_island_data_ch2_d1[10],r_island_data_ch1_d1[10],
                              r_island_data_ch2_d1[9 ],r_island_data_ch1_d1[9 ],r_island_data_ch2_d1[8 ],r_island_data_ch1_d1[8 ],
                              r_island_data_ch2_d1[7 ],r_island_data_ch1_d1[7 ],r_island_data_ch2_d1[6 ],r_island_data_ch1_d1[6 ],
                              r_island_data_ch2_d1[5 ],r_island_data_ch1_d1[5 ],r_island_data_ch2_d1[4 ],r_island_data_ch1_d1[4 ],
                              r_island_data_ch2_d1[3 ],r_island_data_ch1_d1[3 ],r_island_data_ch2_d1[2 ],r_island_data_ch1_d1[2 ],
                              r_island_data_ch2_d1[1 ],r_island_data_ch1_d1[1 ],r_island_data_ch2_d1[0 ],r_island_data_ch1_d1[0 ]}; 
        else  
            O_BCH_block_1 <= 'b0;
    end
end
// BCH块2组装逻辑(通道1&2数据交叉排列)
always @(posedge I_pixel_clk or negedge I_reste_n) begin
    if (!I_reste_n) begin
        O_BCH_block_2 <= 'b0;
    end
    else begin
        if (r_island_data_vaild) 
            O_BCH_block_2 <= {r_island_data_ch2_d2[31],r_island_data_ch1_d2[31],r_island_data_ch2_d2[30],r_island_data_ch1_d2[30],
                              r_island_data_ch2_d2[29],r_island_data_ch1_d2[29],r_island_data_ch2_d2[28],r_island_data_ch1_d2[28], 
                              r_island_data_ch2_d2[27],r_island_data_ch1_d2[27],r_island_data_ch2_d2[26],r_island_data_ch1_d2[26], 
                              r_island_data_ch2_d2[25],r_island_data_ch1_d2[25],r_island_data_ch2_d2[24],r_island_data_ch1_d2[24],
                              r_island_data_ch2_d2[23],r_island_data_ch1_d2[23],r_island_data_ch2_d2[22],r_island_data_ch1_d2[22], 
                              r_island_data_ch2_d2[21],r_island_data_ch1_d2[21],r_island_data_ch2_d2[20],r_island_data_ch1_d2[20],
                              r_island_data_ch2_d2[19],r_island_data_ch1_d2[19],r_island_data_ch2_d2[18],r_island_data_ch1_d2[18],
                              r_island_data_ch2_d2[17],r_island_data_ch1_d2[17],r_island_data_ch2_d2[16],r_island_data_ch1_d2[16],
                              r_island_data_ch2_d2[15],r_island_data_ch1_d2[15],r_island_data_ch2_d2[14],r_island_data_ch1_d2[14],
                              r_island_data_ch2_d2[13],r_island_data_ch1_d2[13],r_island_data_ch2_d2[12],r_island_data_ch1_d2[12],
                              r_island_data_ch2_d2[11],r_island_data_ch1_d2[11],r_island_data_ch2_d2[10],r_island_data_ch1_d2[10],
                              r_island_data_ch2_d2[9 ],r_island_data_ch1_d2[9 ],r_island_data_ch2_d2[8 ],r_island_data_ch1_d2[8 ],
                              r_island_data_ch2_d2[7 ],r_island_data_ch1_d2[7 ],r_island_data_ch2_d2[6 ],r_island_data_ch1_d2[6 ],
                              r_island_data_ch2_d2[5 ],r_island_data_ch1_d2[5 ],r_island_data_ch2_d2[4 ],r_island_data_ch1_d2[4 ],
                              r_island_data_ch2_d2[3 ],r_island_data_ch1_d2[3 ],r_island_data_ch2_d2[2 ],r_island_data_ch1_d2[2 ],
                              r_island_data_ch2_d2[1 ],r_island_data_ch1_d2[1 ],r_island_data_ch2_d2[0 ],r_island_data_ch1_d2[0 ]};  
        else 
            O_BCH_block_2 <= 'b0;
    end
end 
// BCH块3组装逻辑(通道1&2数据交叉排列)
always @(posedge I_pixel_clk or negedge I_reste_n) begin
    if (!I_reste_n) begin
        O_BCH_block_3 <= 'b0;
    end
    else begin
        if (r_island_data_vaild) 
            O_BCH_block_3 <= {r_island_data_ch2_d3[31],r_island_data_ch1_d3[31],r_island_data_ch2_d3[30],r_island_data_ch1_d3[30],
                              r_island_data_ch2_d3[29],r_island_data_ch1_d3[29],r_island_data_ch2_d3[28],r_island_data_ch1_d3[28], 
                              r_island_data_ch2_d3[27],r_island_data_ch1_d3[27],r_island_data_ch2_d3[26],r_island_data_ch1_d3[26], 
                              r_island_data_ch2_d3[25],r_island_data_ch1_d3[25],r_island_data_ch2_d3[24],r_island_data_ch1_d3[24],
                              r_island_data_ch2_d3[23],r_island_data_ch1_d3[23],r_island_data_ch2_d3[22],r_island_data_ch1_d3[22], 
                              r_island_data_ch2_d3[21],r_island_data_ch1_d3[21],r_island_data_ch2_d3[20],r_island_data_ch1_d3[20],
                              r_island_data_ch2_d3[19],r_island_data_ch1_d3[19],r_island_data_ch2_d3[18],r_island_data_ch1_d3[18],
                              r_island_data_ch2_d3[17],r_island_data_ch1_d3[17],r_island_data_ch2_d3[16],r_island_data_ch1_d3[16],
                              r_island_data_ch2_d3[15],r_island_data_ch1_d3[15],r_island_data_ch2_d3[14],r_island_data_ch1_d3[14],
                              r_island_data_ch2_d3[13],r_island_data_ch1_d3[13],r_island_data_ch2_d3[12],r_island_data_ch1_d3[12],
                              r_island_data_ch2_d3[11],r_island_data_ch1_d3[11],r_island_data_ch2_d3[10],r_island_data_ch1_d3[10],
                              r_island_data_ch2_d3[9 ],r_island_data_ch1_d3[9 ],r_island_data_ch2_d3[8 ],r_island_data_ch1_d3[8 ],
                              r_island_data_ch2_d3[7 ],r_island_data_ch1_d3[7 ],r_island_data_ch2_d3[6 ],r_island_data_ch1_d3[6 ],
                              r_island_data_ch2_d3[5 ],r_island_data_ch1_d3[5 ],r_island_data_ch2_d3[4 ],r_island_data_ch1_d3[4 ],
                              r_island_data_ch2_d3[3 ],r_island_data_ch1_d3[3 ],r_island_data_ch2_d3[2 ],r_island_data_ch1_d3[2 ],
                              r_island_data_ch2_d3[1 ],r_island_data_ch1_d3[1 ],r_island_data_ch2_d3[0 ],r_island_data_ch1_d3[0 ]};
        else 
            O_BCH_block_3 <= 'b0;
    end
end  
// BCH块4组装逻辑(直接赋值)    
always @(posedge I_pixel_clk or negedge I_reste_n) begin
    if (!I_reste_n) begin
        O_BCH_block_4 <= 'b0;
    end
    else begin
        if (r_island_data_vaild) 
            O_BCH_block_4 <= r_island_data_ch0_d2;
        else 
            O_BCH_block_4 <= 'b0;
    end
end     
endmodule
该模块为HDMI音频包解码器,主要负责从BCH编码数据块中提取并校验音频信息。通过BCH_32_24和BCH_64_56双校验单元对包头和音频数据进行纠错验证,采用两级寄存器锁存保证时序同步,通过同步FIFO实现音频数据缓冲。当检测到有效音频包(包头标识0x02且双校验通过)时,将24位PCM立体声数据分离为左右声道输出,并配合外部请求信号实现流量控制,满足HDMI 1.4b规范对音频数据包的处理要求,确保音频流传输的完整性和实时性。 
 4代码仿真复制代码`timescale 1ns / 1ps  
//////////////////////////////////////////////////////////////////////////////////  
// 模块功能:HDMI音频数据提取与校验  
// 设计规范:  
// 1. 同步复位(低电平有效)  
// 2. 严格遵循IEEE 1364-2001 Verilog标准  
// 3. 所有输出寄存器复位初始化  
// 4. 模块端口符合输入/输出方向命名规范  
//////////////////////////////////////////////////////////////////////////////////  
module hdmi_audio_packet_decoder(  
    // 系统基础信号  
    input  wire         I_pixel_clk,       // 像素时钟 
    input  wire         I_reset_n,         // 低有效异步复位 
    
    // BCH数据块输入接口  
    input  wire [63:0]  I_BCH_block_0,     // BCH编码数据块0  
    input  wire [63:0]  I_BCH_block_1,     // BCH编码数据块1   
    input  wire [63:0]  I_BCH_block_2,     // BCH编码数据块2  
    input  wire [63:0]  I_BCH_block_3,     // BCH编码数据块3  
    input  wire [31:0]  I_BCH_block_4,     // BCH编码包头数据 
    input  wire         I_block_data_vaild,// 块数据有效标志 
    input  wire         I_audio_packet_req,
    // 音频输出接口  
    output reg          O_audio_valid,     // 音频数据有效信号
    output reg [23:0]   O_audio_left_data, // 左声道PCM数据 
    output reg [23:0]   O_audio_right_data // 右声道PCM数据 
);  
//------------------------------------------------------------------------------  
// 内部信号声明(严格位宽声明)  
//------------------------------------------------------------------------------  
wire        w_fifo_full  ;    
wire        w_fifo_empty ;
wire [7:0]  w_header_ecc, w_body_ecc;        // ECC校验结果  
wire [7:0]  w_header_ecc_base, w_body_ecc_base; // ECC传输结果
wire [23:0] w_header;
wire [55:0] w_body;
wire [63:0] w_fifo_dout;
wire [63:0] w_audio_data;
wire        w_rd_en;
reg         r_audio_valid; 
reg  [63:0] r_BCH_block_0;   // 数据块0寄存器  
reg  [63:0] r_BCH_block_1;   // 数据块1寄存器  
reg  [63:0] r_BCH_block_2;   // 数据块2寄存器  
reg  [63:0] r_BCH_block_3;   // 数据块3寄存器  
reg  [31:0] r_BCH_block_4;   // 包头数据寄存器  
reg  [63:0] r_BCH_block_0d;   // 数据块0寄存器  
reg  [63:0] r_BCH_block_1d;   // 数据块1寄存器  
reg  [63:0] r_BCH_block_2d;   // 数据块2寄存器  
reg  [63:0] r_BCH_block_3d;   // 数据块3寄存器  
reg  [31:0] r_BCH_block_4d;   // 包头数据寄存器  
//------------------------------------------------------------------------------  
// BCH校验逻辑(严格时序控制)  
//------------------------------------------------------------------------------  
assign w_header_ecc_base = r_BCH_block_4[31:24];   // 包头校验码提取  
assign w_body_ecc_base   = r_BCH_block_0[63:56];   // 包体验证码提取  
assign w_header          = I_BCH_block_4[23:0];
assign w_body            = I_BCH_block_0[55:0];
assign w_rd_en           = w_fifo_empty ? 1'b0 : I_audio_packet_req;      //非空时才接入需求信号
assign w_audio_data      = w_fifo_empty ? 64'h000000 : w_fifo_dout; //数据速度不够发送静音数据
BCH_32_24_encode u_BCH_32_24_encode(
    .I_clk         (I_pixel_clk ),
    .I_data_in     (w_header    ),
    .O_bch_ecc_out (w_header_ecc)
);
BCH_64_56_encode u_BCH_64_56_encode(
    .I_clk         (I_pixel_clk),
    .I_data_in     (w_body     ),
    .O_bch_ecc_out (w_body_ecc )
);
//------------------------------------------------------------------------------  
// 数据锁存逻辑(严格时序控制)  
//------------------------------------------------------------------------------  
always @(posedge I_pixel_clk or negedge I_reset_n) begin  
    if (!I_reset_n) begin  
        // 异步复位初始化  
        r_BCH_block_0 <= 64'h0;  
        r_BCH_block_1 <= 64'h0;  
        r_BCH_block_2 <= 64'h0;  
        r_BCH_block_3 <= 64'h0;  
        r_BCH_block_4 <= 32'h0;  
    end  
    else if (I_block_data_vaild) begin  
        // 数据有效时锁存整个数据包  
        r_BCH_block_0 <= I_BCH_block_0;  
        r_BCH_block_1 <= I_BCH_block_1;  
        r_BCH_block_2 <= I_BCH_block_2;  
        r_BCH_block_3 <= I_BCH_block_3;   
        r_BCH_block_4 <= I_BCH_block_4; 
    end  
    else begin
        r_BCH_block_0 <= 64'h0;
        r_BCH_block_1 <= 64'h0;
        r_BCH_block_2 <= 64'h0;
        r_BCH_block_3 <= 64'h0;
        r_BCH_block_4 <= 32'h0;
    end
end  
always @(posedge I_pixel_clk or negedge I_reset_n) begin  
    if (!I_reset_n) begin  
        // 异步复位初始化  
        r_BCH_block_0d <= 64'h0;  
        r_BCH_block_1d <= 64'h0;  
        r_BCH_block_2d <= 64'h0;  
        r_BCH_block_3d <= 64'h0;  
        r_BCH_block_4d <= 32'h0;  
    end  
    else  begin  
        r_BCH_block_0d <= r_BCH_block_0;  
        r_BCH_block_1d <= r_BCH_block_1;  
        r_BCH_block_2d <= r_BCH_block_2;  
        r_BCH_block_3d <= r_BCH_block_3;   
        r_BCH_block_4d <= r_BCH_block_4; 
    end  
end  
//------------------------------------------------------------------------------  
// 音频数据提取逻辑(满足建立/保持时间)  
//------------------------------------------------------------------------------  
always @(posedge I_pixel_clk or negedge I_reset_n) begin  
    if (!I_reset_n) begin  
        // 复位时清空音频输出  
        r_audio_valid <= 1'b0;  
    end  
    else begin  
        // 复合校验条件:包头类型+双校验通过  
        if ((r_BCH_block_4[7:0] == 8'h02) && (w_header_ecc == w_header_ecc_base) &&  (w_body_ecc == w_body_ecc_base))begin  
            if ((r_BCH_block_0[55:0] != 56'h00)) 
                r_audio_valid <= 1'b1;  
            else 
                r_audio_valid <= 1'b0;  
        end  
        else   
            r_audio_valid <= 1'b0;  // 保持数据有效信号严格单周期  
    end  
end  
//=======================================================================  
// 包有效状态机
//=======================================================================  
always @(posedge I_pixel_clk or negedge I_reset_n) begin  
    if (!I_reset_n) begin  
        O_audio_valid <= 1'b0;  
    end else begin  
        if (I_audio_packet_req && !w_fifo_empty) begin  
            O_audio_valid <= 1'b1;
        end else begin  
            O_audio_valid <= 1'b0;  
        end  
    end  
end  
always @(posedge I_pixel_clk or negedge I_reset_n) begin  
    if (!I_reset_n) begin  
        O_audio_right_data <= 'b0;  
    end else begin  
        O_audio_right_data <= w_audio_data[47:24]; 
    end  
end  
always @(posedge I_pixel_clk or negedge I_reset_n) begin  
    if (!I_reset_n) begin  
        O_audio_left_data <= 'b0;  
    end else begin  
        O_audio_left_data <= w_audio_data[23:0]; 
    end  
end  
xpm_fifo_sync #(    
    .DOUT_RESET_VALUE    ("0"     ), // 复位输出值  
    .ECC_MODE            ("no_ecc"), // 关闭ECC校验  
    .FIFO_MEMORY_TYPE    ("auto"  ), // 自动选择存储类型  
    .FIFO_READ_LATENCY   (1       ), // 标准模式读延迟  
    .FIFO_WRITE_DEPTH    (1024    ), // 物理深度=2^log2(FIFO_DEPTH)  
    .FULL_RESET_VALUE    (0       ), // 复位时FULL信号状态  
    .READ_DATA_WIDTH     (64      ), // 必须与WRITE_DATA_WIDTH成整数倍关系  
    .READ_MODE           ("fwft"  ), // 推荐使用FWFT模式降低延迟  
    .SIM_ASSERT_CHK      (0       ), // 关闭仿真断言  
    .WRITE_DATA_WIDTH    (64      )  // 必须与READ_DATA_WIDTH匹配或成比例  
) u_audio_fifo (  
    .rst        (!I_reset_n                      ), // 异步复位连接  
    .wr_clk     (I_pixel_clk                     ),  
    .wr_en      (r_audio_valid                   ),  
    .din        ({16'h0000, r_BCH_block_0d[47:0]}),  
    .full       (w_fifo_full                     ),  
    .rd_en      (w_rd_en                         ),  
    .dout       (w_fifo_dout                     ),  
    .empty      (w_fifo_empty                    )  
);  
endmodule
4.1 data_island_bch_assembler.v模块仿真
 检查解析出的BCH block数据,BCH block4数据就是Header包数据,BCH block0数据是Body包数据,符合模拟发送的数据。   恢复出的island data中的HSYNC和VSYNC数据。   4.2 hdmi_audio_packet_decoder.v模块仿真
 从仿真结果看,左右声道数据解析为24bit的24’h7FFFF0,符合我们仿真发送的原始数据,模块校验通过。   
 |