FPGA实现HDMI传输(二)

news2024/9/23 7:33:16

之前的文章简单介绍了HDMI接口、TMDS编码以及ADV611工作原理和寄存器配置,本篇博客将给出具体的代码以及板级验证结果,代码参考自米联客的教程。

一.ADV7611配置

1.i2c驱动模块

`timescale 1ns / 1ps

module uii2c#
(
    parameter       WMEN_LEN        =       8'd0,                                           //写入字节长度
    parameter       RMEN_LEN        =       8'd0,                                           //读出字节长度
    parameter       CLK_DIV         =       16'd499                                         //i2c时钟分频系数
)
(
    input                                       clk_i,                                      //系统时钟
    input            [7:0]                      rd_cnt,                                     //读数据长度,包含器件地址
    input                                       iic_en,                                     //i2c使能信号
    input                                       iic_mode,                                   //i2c工作模式
    input            [WMEN_LEN*8-1'b1:0]        wr_data,                                    //写入数据
    input            [7:0]                      wr_cnt,                                     //写数据长度,包含器件地址

    output       reg [RMEN_LEN*8-1'b1:0]        rd_data     =   0,                          //读取数据
    output       reg                            iic_scl     =   0 ,                         //i2c时钟总线
    output       reg                            iic_busy    =   0,                          //i2c忙碌,拉高时不进行操作
    inout        wire                           iic_sda,                                    //i2c数据总线
    output       reg                            sda_dg      =   1'b1                        //用于调试
);

    parameter               IDLE        =       4'd0;                                       //空闲状态
    parameter               START       =       4'd1;                                       //开始
    parameter               W_WAIT      =       4'd2;                                       //写入数据
    parameter               W_ACK       =       4'd3;                                       //写响应
    parameter               R_WAIT      =       4'd4;                                       //读取数据
    parameter               R_ACK       =       4'd5;                                       //读响应
    parameter               STOP1       =       4'd6;                                       //停止信号1
    parameter               STOP2       =       4'd7;                                       //停止信号2

    parameter               OFFSET      =       CLK_DIV - CLK_DIV/4;                        //产生i2c时钟

    reg         [2:0]       IIC_S       =       4'd0;                                       //i2c工作状态
    reg         [15:0]      clkdiv      =       16'd0;                                      //时钟分频计数器
    reg                     scl_clk     =       1'b0;                                       //i2c工作时钟
    reg                     scl_r       =       1'b1;                                       //i2c时钟寄存器
    reg                     sda_o       =       1'b0;                                       //sda输出
    reg         [7:0]       sda_r       =       8'd0;                                       //i2c数据寄存器
    reg         [7:0]       sda_i_r     =       8'd0;                                       //i2c输入数据寄存器
    reg         [7:0]       wcnt        =       8'd0;                                       //写数据计数
    reg         [7:0]       rcnt        =       8'd0;                                       //读数据计数
    reg         [2:0]       bcnt        =       3'd0;                                       //读写字节计数
    reg                     rd_en       =       1'b0;                                       //读使能
    reg                     iic_sda_r   =       1'b1;                                       //数据总线缓存

    wire                    scl_offset  =       (clkdiv == OFFSET);                         //scl delay output to fit timing
    wire                    sda_i;                                                          //i2c数据总线输入
 
    //利用计数器产生i2c驱动时钟
    always@(posedge clk_i)begin
        if(clkdiv < CLK_DIV)    
            clkdiv <= clkdiv + 1'b1;
        else begin
            clkdiv <= 16'd0; 
            scl_clk <= !scl_clk;
        end
    end

    //三态门处理
    IOBUF #(
        .DRIVE(12), // Specify the output drive strength
        .IBUF_LOW_PWR("TRUE"),  // Low Power - "TRUE", High Performance = "FALSE" 
        .IOSTANDARD("DEFAULT"), // Specify the I/O standard
        .SLEW("SLOW") // Specify the output slew rate
    ) IOBUF_inst (
        .O(sda_i),    // Buffer output
        .IO(iic_sda), // Buffer inout port (connect directly to top-level port)
        .I(sda_o),    // Buffer input
        .T(sda_o)     // 3-state enable input, high=input, low=output
    );

    //时钟总线输出    
    always @(posedge clk_i) 
        iic_scl <=  scl_offset ?  scl_r : iic_scl;       

    PULLUP PULLUP_inst (.O(iic_sda));
    
    always @(*) begin
        if(IIC_S == IDLE || IIC_S == STOP1 || IIC_S == STOP2)
            scl_r <= 1'b1;
        else 
            scl_r <= ~scl_clk;
    end   
    //sda output 
    always @(*) begin
        if(IIC_S == START || IIC_S == STOP1 || (IIC_S == R_ACK && (rcnt != rd_cnt)))
            sda_o <= 1'b0;
        else if(IIC_S == W_WAIT)
            sda_o <= sda_r[7]; 
        else  
            sda_o <= 1'b1;
    end   

    //sda输出转换
    always @(negedge scl_clk) begin
        if(IIC_S == W_ACK || IIC_S == START)begin
            sda_r <= wr_data[(wcnt*8) +: 8];
            if( rd_en ) sda_r <= {wr_data[7:1],1'b1};
        end
        else if(IIC_S == W_WAIT)
            sda_r <= {sda_r[6:0],1'b1};
        else 
            sda_r <= sda_r;
    end

    //sda输入转换  
    always @(posedge scl_clk) begin
        if(IIC_S == R_WAIT ||IIC_S == W_ACK ) begin
            sda_i_r <= {sda_i_r[6:0],sda_i};
        end
        else if(IIC_S == R_ACK)
            rd_data[((rcnt-1'b1)*8) +: 8] <= sda_i_r[7:0];
        else if(IIC_S == IDLE)begin
            sda_i_r <= 8'd0;
        end 
    end

    always @(posedge scl_clk) 
        iic_sda_r <= sda_i;

    always @(posedge clk_i) 
        sda_dg <= sda_i;

    //iic状态机
    always @(negedge scl_clk)begin
        case(IIC_S) //sda = 1 scl =1
            IDLE://idle wait iic_en == 1'b1 start trasmit   rd_en == 1'b1 restart 
            if(iic_en == 1'b1 || rd_en == 1'b1)begin 
                iic_busy <= 1'b1;        
                IIC_S  <= START;
            end
        else begin
           iic_busy <= 1'b0;
           wcnt <= 8'd0;
           rcnt <= 8'd0;
           rd_en <= 1'b0;
        end
        START:begin //sda = 0  then scl_clk =0 scl =0 generate start
           bcnt <= 3'd7;          
           IIC_S  <= W_WAIT;
        end           
        W_WAIT://write data 
        begin
           if(bcnt > 3'd0)
               bcnt  <= bcnt - 1'b1; 
           else begin
               wcnt <= wcnt + 1'b1; 
               IIC_S  <= W_ACK;
           end
        end 
        W_ACK://write data ack
        begin 
           if(wcnt < wr_cnt)begin 
              bcnt <= 3'd7;
              IIC_S <= W_WAIT;
           end
           else if(rd_cnt > 3'd0)begin// read data
              if(rd_en == 1'b0 && iic_mode == 1'b1)begin 
                  rd_en <= 1'b1;
                  IIC_S <= IDLE;  
              end
              else 
                  IIC_S <= R_WAIT;
              bcnt <= 3'd7;
           end
           else
              IIC_S <= STOP1; 
              if(iic_sda_r == 1'b1)
              IIC_S <= STOP1;
        end  
        R_WAIT://read data
        begin
           rd_en <= 1'b0;
           bcnt  <= bcnt - 1'b1; 
           if(bcnt == 3'd0)begin
              rcnt <= (rcnt < rd_cnt) ? (rcnt + 1'b1) : rcnt;
              IIC_S  <= R_ACK;
           end
        end
        R_ACK://read date ack
        begin
           bcnt <= 3'd7;
           IIC_S <= (rcnt < rd_cnt) ? R_WAIT : STOP1; 
        end  
        STOP1://sda = 0 scl = 1
            IIC_S <= STOP2;
        STOP2://sda = 1 scl = 1
            IIC_S <= IDLE;          
        default:
            IIC_S <= IDLE;
    endcase
end

endmodule

2.adv7611寄存器数据

`timescale 1ns / 1ps

module ui7611reg(
    input               [8 :0]              REG_INDEX,                      //对已配置寄存器计数

    output          reg [31:0]              REG_DATA,                       //寄存器地址+写入数据
    output              [8 :0]              REG_SIZE                        //需配置寄存器个数
);

    assign	                                REG_SIZE    =   9'd182;

//-----------------------------------------------------------------
/	Config Data REG	  //	
always@(*)
case(REG_INDEX)
//write Data Index
    0   : REG_DATA	=	{8'h98,8'hF4, 8'h80};	//Manufacturer ID Byte - High (Read only)
    1   : REG_DATA	=	{8'h98,8'hF5, 8'h7c};	//Manufacturer ID Byte - Low (Read only)
    2   : REG_DATA	= 	{8'h98,8'hF8, 8'h4c};	// BIT[7]-Reset all the Reg 
    3   : REG_DATA	= 	{8'h98,8'hF9, 8'h64};	//DC offset for analog process
    4   : REG_DATA	= 	{8'h98,8'hFA, 8'h6c};	//COM10 : href/vsync/pclk/data reverse(Vsync H valid)
    5   : REG_DATA	= 	{8'h98,8'hFB, 8'h68};	//VGA :	8'h22;	QVGA :	8'h3f;
    6   : REG_DATA	= 	{8'h98,8'hFD, 8'h44};	//VGA :	8'ha4;	QVGA :	8'h50;
    7   : REG_DATA	=	{8'h98,8'h01, 8'h05};	//VGA :	8'h07;	QVGA :	8'h03;
    8   : REG_DATA	= 	{8'h98,8'h00, 8'h1F};	//VGA :	8'hf0;	QVGA :	8'h78;
    9   : REG_DATA	= 	{8'h98,8'h02, 8'hF7};	//HREF	/ 8'h80
    10  : REG_DATA  = 	{8'h98,8'h03, 8'h40};	//VGA :	8'hA0;	QVGA :	8'hF0
    11  : REG_DATA  = 	{8'h98,8'h04, 8'h42};	//VGA :	8'hF0;	QVGA :	8'h78
    12  : REG_DATA	=	{8'h98,8'h05, 8'h28};	//
    13  : REG_DATA	= 	{8'h98,8'h06, 8'ha7};	//
    14  : REG_DATA	= 	{8'h98,8'h0b, 8'h44};	//BIT[6] :	0 :VGA; 1;QVGA
    15  : REG_DATA	= 	{8'h98,8'h0C, 8'h42};	//
    16  : REG_DATA	= 	{8'h98,8'h15, 8'h80};	//
    17  : REG_DATA	= 	{8'h98,8'h19, 8'h8a};	//
    18  : REG_DATA	= 	{8'h98,8'h33, 8'h40};	//
    19  : REG_DATA	= 	{8'h98,8'h14, 8'h3f};	//
    20  : REG_DATA	= 	{8'h44,8'hba, 8'h01};	//
    21  : REG_DATA	= 	{8'h44,8'h7c, 8'h01};	//	
    22  : REG_DATA	= 	{8'h64,8'h40, 8'h81};	//DSP_Ctrl4 :00/01 : YUV or RGB; 10 : RAW8; 11 : RAW10		
    23  : REG_DATA	=	{8'h68,8'h9b, 8'h03};   //ADI recommanded setting
    24  : REG_DATA	=	{8'h68,8'hc1, 8'h01};	//ADI recommanded setting
    25  : REG_DATA	=	{8'h68,8'hc2, 8'h01};	//ADI recommanded setting
    26  : REG_DATA	=	{8'h68,8'hc3, 8'h01};	//ADI recommanded setting
    27  : REG_DATA	=	{8'h68,8'hc4, 8'h01};	//ADI recommanded setting
    28  : REG_DATA	=	{8'h68,8'hc5, 8'h01};	//ADI recommanded setting
    29  : REG_DATA	=	{8'h68,8'hc6, 8'h01};	//ADI recommanded setting
    30  : REG_DATA	=	{8'h68,8'hc7, 8'h01};	//ADI recommanded setting
    31  : REG_DATA	=	{8'h68,8'hc8, 8'h01};	//ADI recommanded setting
    32  : REG_DATA	=	{8'h68,8'hc9, 8'h01};	//ADI recommanded settin g
    33  : REG_DATA	=	{8'h68,8'hca, 8'h01};	//ADI recommanded setting
    34  : REG_DATA	=	{8'h68,8'hcb, 8'h01};	//ADI recommanded setting
    35  : REG_DATA	=	{8'h68,8'hcc, 8'h01};	//ADI recommanded setting
    36  : REG_DATA	=	{8'h68,8'h00, 8'h00}; 	//Set HDMI input Port A
    37  : REG_DATA	=	{8'h68,8'h83, 8'hfe};	//terminator for Port A
    38  : REG_DATA	=	{8'h68,8'h6f, 8'h08};	//ADI recommended setting
    39  : REG_DATA	=	{8'h68,8'h85, 8'h1f};	//ADI recommended setting
    40  : REG_DATA	=	{8'h68,8'h87, 8'h70};	//ADI recommended setting
    41  : REG_DATA	=	{8'h68,8'h8d, 8'h04};	//LFG
    42  : REG_DATA	=	{8'h68,8'h8e, 8'h1e};	//HFG
    43  : REG_DATA	=	{8'h68,8'h1a, 8'h8a};	//unmute audio
    44  : REG_DATA	=	{8'h68,8'h57, 8'hda};	// ADI recommended setting
    45  : REG_DATA	=	{8'h68,8'h58, 8'h01};
    46  : REG_DATA	=	{8'h68,8'h75, 8'h10}; 
    47  : REG_DATA	= 	{8'h68,8'h6c ,8'ha3};//enable manual HPA
    48  : REG_DATA	= 	{8'h98,8'h20 ,8'h70};//HPD low
    49  : REG_DATA	= 	{8'h64,8'h74 ,8'h00};//disable internal EDID 
//edid 
//0: REG_DATA	= 	{8'h68,8'h6c ,8'ha3}; enable manual HPA
//1: REG_DATA	= 	{8'h98,8'h20 ,8'h70};//HPD low
//2: REG_DATA	= 	{8'h64,8'h74 ,8'h00};//disable internal EDID  
//edid par
    50  : REG_DATA	= 	{8'h6c,8'd0  , 8'h00};
    51  : REG_DATA	= 	{8'h6c,8'd1  , 8'hFF};
    52  : REG_DATA	= 	{8'h6c,8'd2  , 8'hFF};
    53  : REG_DATA	= 	{8'h6c,8'd3  , 8'hFF};
    54  : REG_DATA	= 	{8'h6c,8'd4  , 8'hFF};
    55  : REG_DATA	= 	{8'h6c,8'd5  , 8'hFF};
    56  : REG_DATA	= 	{8'h6c,8'd6  , 8'hFF};
    57  : REG_DATA	= 	{8'h6c,8'd7  , 8'h00};
    58  : REG_DATA	= 	{8'h6c,8'd8  , 8'h20};
    59  : REG_DATA	= 	{8'h6c,8'd9  , 8'hA3};
    60  : REG_DATA	= 	{8'h6c,8'd10 , 8'h29};
    61  : REG_DATA	= 	{8'h6c,8'd11 , 8'h00};
    62  : REG_DATA	= 	{8'h6c,8'd12 , 8'h01};
    63  : REG_DATA	= 	{8'h6c,8'd13 , 8'h00};
    64  : REG_DATA	= 	{8'h6c,8'd14 , 8'h00};
    65  : REG_DATA	= 	{8'h6c,8'd15 , 8'h00};
    66  : REG_DATA	= 	{8'h6c,8'd16 , 8'h23};
    67  : REG_DATA	= 	{8'h6c,8'd17 , 8'h12};
    68  : REG_DATA	= 	{8'h6c,8'd18 , 8'h01};
    69  : REG_DATA	= 	{8'h6c,8'd19 , 8'h03};
    70  : REG_DATA	= 	{8'h6c,8'd20 , 8'h80};
    71  : REG_DATA	= 	{8'h6c,8'd21 , 8'h73};
    72  : REG_DATA	= 	{8'h6c,8'd22 , 8'h41};
    73  : REG_DATA	= 	{8'h6c,8'd23 , 8'h78};
    74  : REG_DATA	= 	{8'h6c,8'd24 , 8'h0A};
    75  : REG_DATA	= 	{8'h6c,8'd25 , 8'hF3};
    76  : REG_DATA	= 	{8'h6c,8'd26 , 8'h30};
    77  : REG_DATA	= 	{8'h6c,8'd27 , 8'hA7};
    78  : REG_DATA	= 	{8'h6c,8'd28 , 8'h54};
    79  : REG_DATA	= 	{8'h6c,8'd29 , 8'h42};
    80  : REG_DATA	= 	{8'h6c,8'd30 , 8'hAA};
    81  : REG_DATA	= 	{8'h6c,8'd31 , 8'h26};
    82  : REG_DATA	= 	{8'h6c,8'd32 , 8'h0F};
    83  : REG_DATA	= 	{8'h6c,8'd33 , 8'h50};
    84  : REG_DATA	= 	{8'h6c,8'd34 , 8'h54};
    85  : REG_DATA	= 	{8'h6c,8'd35 , 8'h25};
    86  : REG_DATA	= 	{8'h6c,8'd36 , 8'hC8};
    87  : REG_DATA	= 	{8'h6c,8'd37 , 8'h00};
    88  : REG_DATA	= 	{8'h6c,8'd38 , 8'h61};
    89  : REG_DATA	= 	{8'h6c,8'd39 , 8'h4F};
    90  : REG_DATA	= 	{8'h6c,8'd40 , 8'h01};
    91  : REG_DATA	= 	{8'h6c,8'd41 , 8'h01};
    92  : REG_DATA	= 	{8'h6c,8'd42 , 8'h01};
    93  : REG_DATA	= 	{8'h6c,8'd43 , 8'h01};
    94  : REG_DATA	= 	{8'h6c,8'd44 , 8'h01};
    95  : REG_DATA	= 	{8'h6c,8'd45 , 8'h01};
    96  : REG_DATA	= 	{8'h6c,8'd46 , 8'h01};
    97  : REG_DATA	= 	{8'h6c,8'd47 , 8'h01};
    98  : REG_DATA	= 	{8'h6c,8'd48 , 8'h01};
    99  : REG_DATA	= 	{8'h6c,8'd49 , 8'h01};
    100  : REG_DATA	= 	{8'h6c,8'd50 , 8'h01};
    101  : REG_DATA	= 	{8'h6c,8'd51 , 8'h01};
    102  : REG_DATA	= 	{8'h6c,8'd52 , 8'h01};
    103  : REG_DATA	= 	{8'h6c,8'd53 , 8'h01};
    104  : REG_DATA	= 	{8'h6c,8'd54 , 8'h02};
    105  : REG_DATA	= 	{8'h6c,8'd55 , 8'h3A};
    106  : REG_DATA	= 	{8'h6c,8'd56 , 8'h80};
    107  : REG_DATA	= 	{8'h6c,8'd57 , 8'h18};
    108  : REG_DATA	= 	{8'h6c,8'd58 , 8'h71};
    109  : REG_DATA	= 	{8'h6c,8'd59 , 8'h38};
    110  : REG_DATA	= 	{8'h6c,8'd60 , 8'h2D};
    111  : REG_DATA	= 	{8'h6c,8'd61 , 8'h40};
    112  : REG_DATA	= 	{8'h6c,8'd62 , 8'h58};
    113  : REG_DATA	= 	{8'h6c,8'd63 , 8'h2C};
    114  : REG_DATA	= 	{8'h6c,8'd64 , 8'h45};
    115  : REG_DATA	= 	{8'h6c,8'd65 , 8'h00};
    116  : REG_DATA	= 	{8'h6c,8'd66 , 8'h80};
    117  : REG_DATA	= 	{8'h6c,8'd67 , 8'h88};
    118  : REG_DATA	= 	{8'h6c,8'd68 , 8'h42};
    119  : REG_DATA	= 	{8'h6c,8'd69 , 8'h00};
    120  : REG_DATA	= 	{8'h6c,8'd70 , 8'h00};
    121  : REG_DATA	= 	{8'h6c,8'd71 , 8'h1E};
    122  : REG_DATA	= 	{8'h6c,8'd72 , 8'h8C};
    123  : REG_DATA	= 	{8'h6c,8'd73 , 8'h0A};
    124  : REG_DATA	= 	{8'h6c,8'd74 , 8'hD0};
    125  : REG_DATA	= 	{8'h6c,8'd75 , 8'h8A};
    126  : REG_DATA	= 	{8'h6c,8'd76 , 8'h20};
    127  : REG_DATA	= 	{8'h6c,8'd77 , 8'hE0};
    128  : REG_DATA	= 	{8'h6c,8'd78 , 8'h2D};
    129  : REG_DATA	= 	{8'h6c,8'd79 , 8'h10};
    130  : REG_DATA	= 	{8'h6c,8'd80 , 8'h10};
    131  : REG_DATA	= 	{8'h6c,8'd81 , 8'h3E};
    132  : REG_DATA	= 	{8'h6c,8'd82 , 8'h96};
    133  : REG_DATA	= 	{8'h6c,8'd83 , 8'h00};
    134  : REG_DATA	= 	{8'h6c,8'd84 , 8'h80};
    135  : REG_DATA	= 	{8'h6c,8'd85 , 8'h88};
    136  : REG_DATA	= 	{8'h6c,8'd86 , 8'h42};
    137  : REG_DATA	= 	{8'h6c,8'd87 , 8'h00};
    138  : REG_DATA	= 	{8'h6c,8'd88 , 8'h00};
    139  : REG_DATA	= 	{8'h6c,8'd89 , 8'h18};
    140  : REG_DATA	= 	{8'h6c,8'd90 , 8'h00};
    141  : REG_DATA	= 	{8'h6c,8'd91 , 8'h00};
    142  : REG_DATA	= 	{8'h6c,8'd92 , 8'h00};
    143  : REG_DATA	= 	{8'h6c,8'd93 , 8'hFC};
    144  : REG_DATA	= 	{8'h6c,8'd94 , 8'h00};
    145  : REG_DATA	= 	{8'h6c,8'd95 , 8'h48};
    146  : REG_DATA	= 	{8'h6c,8'd96 , 8'h44};
    147  : REG_DATA	= 	{8'h6c,8'd97 , 8'h4D};
    148  : REG_DATA	= 	{8'h6c,8'd98 , 8'h49};
    149  : REG_DATA	= 	{8'h6c,8'd99 , 8'h20};
    150  : REG_DATA	= 	{8'h6c,8'd100 , 8'h20};
    151  : REG_DATA	= 	{8'h6c,8'd101 , 8'h20};
    152  : REG_DATA	= 	{8'h6c,8'd102 , 8'h20};
    153  : REG_DATA	= 	{8'h6c,8'd103 , 8'h0A};
    154  : REG_DATA	= 	{8'h6c,8'd104 , 8'h20};
    155  : REG_DATA	= 	{8'h6c,8'd105 , 8'h20};
    156  : REG_DATA	= 	{8'h6c,8'd106 , 8'h20};
    157  : REG_DATA	= 	{8'h6c,8'd107 , 8'h20};
    158  : REG_DATA	= 	{8'h6c,8'd108 , 8'h00};
    159  : REG_DATA	= 	{8'h6c,8'd109 , 8'h00};
    160  : REG_DATA	= 	{8'h6c,8'd110 , 8'h00};
    161  : REG_DATA	= 	{8'h6c,8'd111 , 8'hFD};
    162  : REG_DATA	= 	{8'h6c,8'd112 , 8'h00};
    163  : REG_DATA	= 	{8'h6c,8'd113 , 8'h32};
    164  : REG_DATA	= 	{8'h6c,8'd114 , 8'h55};
    165  : REG_DATA	= 	{8'h6c,8'd115 , 8'h1F};
    166  : REG_DATA	= 	{8'h6c,8'd116 , 8'h45};
    167  : REG_DATA	= 	{8'h6c,8'd117 , 8'h0F};
    168  : REG_DATA	= 	{8'h6c,8'd118 , 8'h00};
    169  : REG_DATA	= 	{8'h6c,8'd119 , 8'h0A};
    170  : REG_DATA	= 	{8'h6c,8'd120 , 8'h20};
    171  : REG_DATA	= 	{8'h6c,8'd121 , 8'h20};
    172  : REG_DATA	= 	{8'h6c,8'd122 , 8'h20};
    173  : REG_DATA	= 	{8'h6c,8'd123 , 8'h20};
    174  : REG_DATA	= 	{8'h6c,8'd124 , 8'h20};
    175  : REG_DATA	= 	{8'h6c,8'd125 , 8'h20};
    176  : REG_DATA	= 	{8'h6c,8'd126 , 8'h01};
    177  : REG_DATA	= 	{8'h6c,8'd127 , 8'h24};
    178  : REG_DATA	= 	{8'h64,8'h74  , 8'h01};// enable internal EDID
    179  : REG_DATA	= 	{8'h98,8'h20  , 8'hf0};// HPD high
    180  : REG_DATA	= 	{8'h68,8'h6c  , 8'ha2};// disable manual HPA	
    181  : REG_DATA	=   {8'h98,8'hf4  , 8'h00};
    default:REG_DATA =0;
endcase


endmodule

3.配置模块顶层

`timescale 1ns / 1ps

module uicfg7611#(
        parameter	        CLK_DIV         =           16'd999
)
(
    input                                   clk_i,                                          //系统时钟
    input                                   rst_n,                                          //系统复位

    output                                  adv_scl,                                        //i2c时钟总线
    inout                                   adv_sda,                                        //i2c数据总线
    output reg                              cfg_done                                        //寄存器配置完成信号
);	
    
    reg                     [8 :0]          rst_cnt     =   9'd0;                           //延迟复位计数器
    reg                                     iic_en;                                         //i2c使能信号
    reg                     [31:0]          wr_data;                                        //寄存器地址+写入数据
    reg                     [1 :0]          TS_S        =   2'd0;                           //状态机工作状态
    reg                     [8 :0]          byte_cnt    =   9'd0;                           //读写字节计数器
    reg                     [8 :0]          REG_INDEX;                                      //寄存器配置
    
    wire                                    iic_busy;                                       //i2c忙碌
    wire                    [23:0]          REG_DATA;
    wire                    [8 :0]          REG_SIZE;

    always@(posedge clk_i) begin
        if(!rst_n)
            rst_cnt <= 9'd0;
        else if(!rst_cnt[8]) 
            rst_cnt <= rst_cnt + 1'b1;
    end

    //状态机工作状态转换以及输出
    always@(posedge clk_i) begin
    if(!rst_cnt[8])begin
        REG_INDEX<= 9'd0;
        iic_en  <= 1'b0;
        wr_data <= 32'd0;
        cfg_done<= 1'b0;
        TS_S    <= 2'd0;    
    end
    else begin
        case(TS_S)
        0:if(cfg_done == 1'b0)
            TS_S <= 2'd1;
        1:if(!iic_busy)begin//write data
            iic_en  <= 1'b1; 
			wr_data[7  :0] <= REG_DATA[23:16];   
			wr_data[15 :8] <= REG_DATA[15: 8];   
			wr_data[23:16] <= REG_DATA[7 : 0];
        end
        else 
            TS_S    <= 2'd2;
        2:begin
            iic_en  <= 1'b0; 
            if(!iic_busy)begin 
			    REG_INDEX<= REG_INDEX + 1'b1;
			    TS_S    <= 2'd3;
            end
        end
        3:begin//read rtc register
            if(REG_INDEX == REG_SIZE)begin
				cfg_done <= 1'b1;
			end
			TS_S 	<= 2'd0;
        end 
    endcase
   end
end

    uii2c#(
        .WMEN_LEN(4),
        .RMEN_LEN(1),
        .CLK_DIV(CLK_DIV)//499 for 50M 999 for 100M
    )
    uii2c_inst(
        .clk_i(clk_i),
        .iic_scl(adv_scl),
        .iic_sda(adv_sda),
        .wr_data(wr_data),
        .wr_cnt(8'd3),//write data max len = 4BYTES
        .rd_data(),   //read not used
        .rd_cnt(8'd0),//read not used
        .iic_mode(1'b0),
        .iic_en(iic_en),
        .iic_busy(iic_busy)
    );
    //7611reg
    ui7611reg  ui7611reg_inst(
        .REG_SIZE(REG_SIZE),
        .REG_INDEX(REG_INDEX),
        .REG_DATA(REG_DATA));   

endmodule

二.HDMI输出

1.TMDS编码

module TMDSEncoder(
    input									    clk		        ,//系统时钟信号;
    input									    rst  	        ,//系统复位信号,高电平有效;

    input				[7 : 0]	                din		        ,//输入待编码数据
    input                                       c0              ,//控制信号C0
    input                                       c1              ,//控制信号c1
    input                                       de              ,//输入数据有效指示信号;
    output reg			[9 : 0]	                q_out	         //编码输出数据
);
    localparam          CTRLTOKEN0      =       10'b1101010100  ;
    localparam          CTRLTOKEN1      =       10'b0010101011  ;
    localparam          CTRLTOKEN2      =       10'b0101010100  ;
    localparam          CTRLTOKEN3      =       10'b1010101011  ;
    
    reg                 [7 : 0]                 din_r           ;//
    reg                 [1 : 0]                 de_r,c0_r,c1_r  ;
    reg                 [3 : 0]                 n1d,n1q_m,n0q_m ;
    reg                 [5 : 0]                 cnt             ;
    reg                 [8 : 0]                 q_m_r           ;

    wire                [8 : 0]                 q_m             ;//
    wire                                        condition1      ;
    wire                                        condition2      ;
    wire                                        condition3      ;
    //统计待编码输入数据中1的个数,最多8个1,所以位宽为4。
    always@(posedge clk)begin
        if(rst)begin//初始值为0;
            n1d <= 4'd0;
        end
        else if(de)begin//当DE为高电平,统计输入数据中1的个数。
            n1d <= din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];
        end
        else begin//当DE为低电平时,对控制信号编码,此时不需要统计输入信号中1的个数,故清零。
            n1d <= 4'd0;
        end
    end
    
    //移位寄存器将输入数据暂存,与后续信号对齐。
    always@(posedge clk)begin
        din_r   <= din;
        de_r    <= {de_r[0],de};
        c0_r    <= {c0_r[0],c0};
        c1_r    <= {c1_r[0],c1};
        q_m_r   <= q_m;
    end

    //判断条件1,输入数据1的个数多余4或者1的个数等于4并且最低位为0时拉高,其余时间拉低。
    assign condition1 = ((n1d > 4'd4) || ((n1d == 4'd4) && (~din_r[0])));
    
    //对输入的信号进行异或运算。
    assign q_m[0] = din_r[0];
    assign q_m[1] = condition1 ? ~((q_m[0] ^ din_r[1])) : (q_m[0] ^ din_r[1]);
    assign q_m[2] = condition1 ? ~((q_m[1] ^ din_r[2])) : (q_m[1] ^ din_r[2]);
    assign q_m[3] = condition1 ? ~((q_m[2] ^ din_r[3])) : (q_m[2] ^ din_r[3]);
    assign q_m[4] = condition1 ? ~((q_m[3] ^ din_r[4])) : (q_m[3] ^ din_r[4]);
    assign q_m[5] = condition1 ? ~((q_m[4] ^ din_r[5])) : (q_m[4] ^ din_r[5]);
    assign q_m[6] = condition1 ? ~((q_m[5] ^ din_r[6])) : (q_m[5] ^ din_r[6]);
    assign q_m[7] = condition1 ? ~((q_m[6] ^ din_r[7])) : (q_m[6] ^ din_r[7]);
    assign q_m[8] = ~condition1;
    
    always@(posedge clk)begin
        if(rst)begin//初始值为0;
            n1q_m <= 4'd0;
            n0q_m <= 4'd0;
        end
        else if(de_r[0])begin//对输入有效数据时,q_m中1和0的个数进行统计;
            n1q_m <= q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
            n0q_m <= 4'd8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);
        end
        else begin//输入数据无效时清零。
            n1q_m <= 4'd0;
            n0q_m <= 4'd0;
        end
    end

    //判断条件2,一行已编码数据中1的个数等于0的个数或者本次编码数据中1的个数等于0的个数。
    assign condition2 = ((cnt == 6'd0) || (n1q_m == n0q_m));
    //判断条件3,已编码数据中1的多余0并且本次编码中间数据1的个数也多与0的个数或者已编码数据中0的个数较多并且此次编码中0的个数也比较多时拉高,其余时间拉低。
    assign condition3 = (((~cnt[5]) && (n1q_m > n0q_m)) || (cnt[5] && (n1q_m < n0q_m)));

    always@(posedge clk)begin
        if(rst)begin//初始值为0;
            cnt <= 6'd0;
            q_out <= 10'd0;
        end
        else if(de_r[1])begin
            q_out[8] <= q_m_r[8];//第8位为编码方式位,直接输出即可。
            if(condition2)begin
                q_out[9] <= ~q_m_r[8];
                q_out[7:0] <= q_m_r[8] ? q_m_r[7:0] : ~q_m_r[7:0];
                //进行cnt的计算;
                cnt <= q_m_r[8] ? (cnt + n1q_m - n0q_m) : (cnt + n0q_m - n1q_m);
            end
            else if(condition3)begin
                q_out[9] <= 1'b1;
                q_out[7:0] <= ~q_m_r[7:0];
                //进行cnt的计算;
                cnt <= cnt + {q_m_r[8],1'b0} + n0q_m - n1q_m;
            end
            else begin
                q_out[9] <= 1'b0;
                q_out[7:0] <= q_m_r[7:0];
                //进行cnt的计算;
                cnt <= cnt - {~q_m_r[8],1'b0} + n1q_m - n0q_m;
            end
        end
        else begin
            cnt <= 6'd0;//对控制信号进行编码时,将计数器清零。
            case ({c1_r[1],c0_r[1]})
                2'b00   : q_out <= CTRLTOKEN0;
                2'b01   : q_out <= CTRLTOKEN1;
                2'b10   : q_out <= CTRLTOKEN2;
                2'b11   : q_out <= CTRLTOKEN3;
            endcase
        end
    end

endmodule

2.并串转换以及差分输出

`timescale 1ns / 1ps

module oserdese2_10to1(
   input                [9:0]             txdata,                                      //输入并行10位数据
   input                                  pclk,                                        //并行数据时钟
   input                                  clkdiv2,                                     //并串转换时钟
   input                                  txrst,                                       //复位信号

   output                                 tx_p,                                        //差分输出
   output                                 tx_n
); 

   wire                 [13:0]            tx_data;
   wire                                   cascade_do, cascade_di, cascade_to, cascade_ti;
   reg                                    int_rst;
   wire                                   dai;

   assign tx_data = {4'd0,txdata[9:0]};                                                //最高支持14位并串转换

   always @(*)
	   if(txrst == 1'b1)
		   int_rst <= 1'b1;
	   else if(pclk)
		   int_rst <= 1'b0;
      else 
         int_rst <= int_rst;
   

OBUFDS #(
      .IOSTANDARD("DEFAULT"), // Specify the output I/O standard
      .SLEW("SLOW")           // Specify the output slew rate
   ) OBUFDS_inst (
      .O(tx_p),     // Diff_p output (connect directly to top-level port)
      .OB(tx_n),   // Diff_n output (connect directly to top-level port)
      .I(dai)      // Buffer input
   );

//----------------------------------------------------------------------------------
//-- Cascaded OSERDES for 10:1 ratio (DDR)
//----------------------------------------------------------------------------------
OSERDESE2 #(
      .DATA_RATE_OQ("DDR"),   // DDR, SDR
      .DATA_RATE_TQ("SDR"),   // DDR, BUF, SDR
      .DATA_WIDTH(10),         // Parallel data width (2-8,10,14)
      .SERDES_MODE("MASTER"), // MASTER, SLAVE
      .TRISTATE_WIDTH(1)      // 3-state converter width (1,4)
   )
   oserdese2_master (
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1(tx_data[0]),
      .D2(tx_data[1]),
      .D3(tx_data[2]),
      .D4(tx_data[3]),
      .D5(tx_data[4]),
      .D6(tx_data[5]),
      .D7(tx_data[6]),
      .D8(tx_data[7]),  
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1(1'b0),
      .T2(1'b0),
      .T3(1'b0),
      .T4(1'b0), 
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1(cascade_di),
      .SHIFTIN2(cascade_ti),
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1(),
      .SHIFTOUT2(),   
      .OCE(1'b1),             // 1-bit input: Output data clock enable    
      .CLK(clkdiv2),        // 1-bit input: High speed clock
      .CLKDIV(pclk),     // 1-bit input: Divided clock                       
      .OQ(dai),               // 1-bit output: Data path output
      .TQ(),               // 1-bit output: 3-state control
      .OFB(),             // 1-bit output: Feedback path for data
      .TBYTEIN(1'b0),     // 1-bit input: Byte group tristate      
      .TBYTEOUT(),   // 1-bit output: Byte group tristate
      .TFB(),             // 1-bit output: 3-state control
      .TCE(1'b0),          // 1-bit input: 3-state clock enable      
      .RST(int_rst)             // 1-bit input: Reset
   );

OSERDESE2 #(
      .DATA_RATE_OQ("DDR"),   // DDR, SDR
      .DATA_RATE_TQ("SDR"),   // DDR, BUF, SDR
      .DATA_WIDTH(10),         // Parallel data width (2-8,10,14)
      .SERDES_MODE("SLAVE"), // MASTER, SLAVE
      .TRISTATE_WIDTH(1)      // 3-state converter width (1,4)
   )
   oserdese2_slave (
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1(1'b0),
      .D2(1'b0),
      .D3(tx_data[8]),
      .D4(tx_data[9]),
      .D5(tx_data[10]),
      .D6(tx_data[11]),
      .D7(tx_data[12]),
      .D8(tx_data[13]),  
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1(1'b0),
      .T2(1'b0),
      .T3(1'b0),
      .T4(1'b0), 
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1(cascade_di),
      .SHIFTOUT2(cascade_ti),         
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1(1'b0),
      .SHIFTIN2(1'b0),
      .OCE(1'b1),             // 1-bit input: Output data clock enable    
      .CLK(clkdiv2),        // 1-bit input: High speed clock
      .CLKDIV(pclk),     // 1-bit input: Divided clock                       
      .OQ(),               // 1-bit output: Data path output
      .TQ(),               // 1-bit output: 3-state control
      .OFB(),             // 1-bit output: Feedback path for data
      .TFB(),             // 1-bit output: 3-state control
      .TBYTEIN(1'b0),     // 1-bit input: Byte group tristate      
      .TBYTEOUT(),   // 1-bit output: Byte group tristate
      .TCE(1'b0),          // 1-bit input: 3-state clock enable      
      .RST(int_rst)             // 1-bit input: Reset
   ); 
    
endmodule

三.顶层模块

`timescale 1ns / 1ps

module top(
    input                                               clk_i,                              //系统时钟
    input                                               hs_i,                               //行同步信号
    input                                               vs_i,                               //场同步信号
    input                                               de_i,                               //数据有效信号
    input                                               pclk_i,                             //像素时钟
    input               [23:0]                          rgb_i,                              //输入图像数据

    output                                              adv_rst,                            //adv7611复位信号
    output                                              adv_scl,                            //时钟总线
    inout                                               adv_sda,                            //数据总线
    output                                              HDMI_CLK_P,                         //差分时钟输出
    output                                              HDMI_CLK_N,
    output              [2:0]                           HDMI_TX_P,                          //差分数据输出
    output              [2:0]                           HDMI_TX_N
);

    assign                                              adv_rst = 1'b1;                     
    wire                                                cfg_done;                           //寄存器配置完成信号
    wire                                                locked ;                            //锁相环工作完成信号
    wire                                                pclkx1,pclkx5;                      //锁相环输出时钟
    reg                                                 hs_r_0,hs_r_1,hs_r;                 
    reg                                                 vs_r_0,vs_r_1,vs_r;
    reg                                                 de_r_0,de_r_1,de_r;
    reg                 [23:0]                          rgb_r_0;
    reg                 [23:0]                          rgb_r_1;
    reg                 [23:0]                          rgb_r;
    wire                                                rst_o1,rst_o2;
    wire                                                vid_rst,vid_clk,vid_vs,vid_hs,vid_de;
    reg                                                 tpg_vs_r = 1'b0;
    reg                                                 tpg_hs_r = 1'b0;


clk_wiz_0 clk_wiz_inst(
    .clk_out1(pclkx1),
    .clk_out2(pclkx5),
    .locked(locked), 
    .clk_in1(pclk_i));

uihdmitx uihdmitx_inst
(
.RSTn_i(cfg_done&&locked),
.HS_i(hs_i),
.VS_i(vs_i),
.VDE_i(de_i),
.RGB_i({rgb_i[7:0],rgb_i[15:8],rgb_i[23:16]}),
.PCLKX1_i(pclkx1),
.PCLKX2_5_i(1'b0),
.PCLKX5_i(pclkx5),
.TMDS_TX_CLK_P(HDMI_CLK_P),
.TMDS_TX_CLK_N(HDMI_CLK_N),
.TMDS_TX_P(HDMI_TX_P),
.TMDS_TX_N(HDMI_TX_N)
);

uicfg7611 uicfg7611_inst
(
.clk_i(clk_i),
.rst_n(1'b1), 
.adv_scl(adv_scl),
.adv_sda(adv_sda),
.cfg_done(cfg_done)
);


 
endmodule

四.板级验证

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2084810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git使用教程(小白也能看懂)

git的使用教程&#xff08;学习和工作中都能用到&#xff09; 1、所需工具 git bash 1&#xff09;安装git bash 官网&#xff1a;https://git-scm.com/download/win 2&#xff09;在文件夹空白处鼠标右键 若出现 上图说明安装成功 2、使用 1&#xff09;我们想要克隆一…

DHT11 实现温湿度传感器

DHT11 DHT11是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;它结合了电阻式感湿元件和一个NTC测温元件&#xff0c;并与一个高性能8位单片机相连接。通过采用专用的数字模块采集技术和温湿度传感技术&#xff0c;DHT11确保了产品的高可靠性和长期稳定性 DHT11时序…

android studio 新建java工程, 安卓新建项目,android studio2024 如何新建java项目

主要解决&#xff0c;新增安卓工程&#xff0c;没有java选项 1. 点击左上角FIle -> New -> 2. 选择 no activity 选项&#xff0c; 然后next 3. langua 就可以选择java 了。name自己定义项目名称&#xff0c;项目存储地址&#xff0c;包名。 配置完成选择finish. 4. fin…

【C++】vector(下)--上篇

个人主页~ vector&#xff08;上&#xff09;~ vector 二、vector的模拟实现1、了解组成2、vector.h&#xff08;1&#xff09;为什么有了size_t参数的vector构造函数还要再写一个int参数的重载vector构造函数&#xff08;2&#xff09;为什么reserve不用memcpy&#xff08;3&…

Mysql剖析(三)----MySql的事务详解

事务&#xff08;Transaction&#xff09;&#xff1a;一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中的各种数据项的一个程序执行单元&#xff08;unit&#xff09;。事务通常由高级数据库操纵语言或编程语言(如SQL、C或Java)书写的用户程序的执行所引…

Python脚本实现向飞书发送卡片消息

目录 1 先创建一个卡片消息2 Python脚本2.1 告警测试2.2 告警恢复 总结 1 先创建一个卡片消息 飞书卡片搭建工具 根据自己的需要创建一个消息卡片&#xff1a; 可以在 卡片源代码 中看到这个卡片的代码信息 2 Python脚本 2.1 告警测试 test.py 文件 ""&quo…

MacOS安装Docker Desktop

目录 安装Docker Desktop 1.下载 2.安装 3.验证 安装Docker Desktop 1.下载 访问Docker官方网站下载页面&#xff1a;https://www.docker.com/products/docker-desktop 选择自己所需的版本下载即可 2.安装 3.验证 1.查询版本号 docker --version 2.也可以运行一个简单的…

【vue、Electron】搭建一个Electron vue项目过程、将前端页面打包成exe 桌面应用

文章目录 前言使用 electron-vue 创建项目1. 安装 vue-cli&#xff08;如果未安装&#xff09;2. 使用 electron-vue 模板创建项目3. 安装和配置 electron-builder4. 运行Electron项目5. 打包应用 可能遇到的问题解决Electron vue首次启动巨慢无法加载执行npm run electron:bui…

从地图信息实时检测路口的各向通行状况、红绿灯及溢出情况

高德地图、百度地图都能获得实时的道路信息。 C# 编写的路况信息爬虫可获得准实时&#xff08;1分钟间隔&#xff09;的路口的各向通行状况、红绿灯及溢出情况。 优势&#xff1a; 投入少&#xff0c;效果好&#xff0c;无需安装设备&#xff1b; 缺陷&#xff1a; 时间间隔…

数据集不够用?3DGS助力生成带标注的全新扩展数据!

作者主页&#xff1a;https://louiszengcn.github.io/ 论文标题&#xff1a; Realistic Surgical Image Dataset Generation Based On 3D Gaussian Splatting 导读&#xff1a; 近年来&#xff0c;随着AI技术的飞速发展&#xff0c;数据量的增加为数据驱动的神经网络提供了更强…

汽车免拆诊断案例 | 2012 款大众速腾车发动机偶尔抖动

故障现象 一辆2012款大众速腾车&#xff0c;搭载CST发动机和干式双离合变速器&#xff0c;累计行驶里程约为17万km。车主反映&#xff0c;发动机偶尔抖动。 故障诊断 接车后试车&#xff0c;确认发动机怠速偶尔抖动&#xff0c;且在D挡起步时抖动明显。用故障检测仪检测&…

专题◉万字长文!盘点过去一年最出圈的Prompt项目教程,有3份在悄悄更新

1. OpenAI 官方出品 | 提示工程最权威的教程 (最新版) 2023年6月&#xff0c;OpenAI 发布了一篇〖*GPT Best Practice (GPT 最佳实践)* 〗教程&#xff0c;详细介绍 ChatGPT Prompt 交互策略&技巧&#xff0c;并且给出了示例说明。 一年时间过去了&#xff0c;OpenAI 不…

Unity射击游戏开发教程:(33)控制飞机左右移动

在本文中,我将介绍如何在玩家朝该方向移动时添加向左和向右转动的动画。 我们已经将左转和右转动画导入到我们的项目中。在我使用的动画中,它们只有两帧,因为我们希望飞机倾斜得很快,这样玩家在按下相应按钮时就能直接感觉到转弯。 </

为什么帕金森病患者在紧张或焦虑状态下震颤会加重?

为什么帕金森病患者在紧张或焦虑状态下震颤会加重&#xff1f; 帕金森病患者在紧张或焦虑状态下震颤加重的原因可能与多个因素有关。首先&#xff0c;帕金森病与大脑中多巴胺水平的降低有关&#xff0c;这种神经递质的失衡会影响运动控制。当患者感到紧张时&#xff0c;大脑皮…

嵌入式软件开发之状态机与事件驱动分析

状态机是一种程序架构,事件驱动也是一种程序架构,在某些开发场景里面,两者是可以一同合并使用的。 事件驱动的概念 生活中有很多事件驱动的例子,上自习瞒着老师偷睡觉就是很生动的一个。 我们都是从高中时代走过来的,高中的学生苦啊,觉得睡觉是世界上最奢侈的东西, 有时…

运维监控工具 PIGOSS BSM :PostgreSQL数据库监控指标

在PostgreSQL数据库中&#xff0c;为了确保其稳定运行和性能优化&#xff0c;我们需要监控一系列关键的指标。以下是一些主要的PostgreSQL监控指标介绍&#xff1a; 连接数&#xff08;Connections&#xff09;&#xff1a; 定义&#xff1a;连接数是指当前正在与数据库建立连…

数据库管理-第236期 数据库一体机的价值(20240829)

数据库管理236期 2024-08-29 数据库管理-第236期 数据库一体机的价值&#xff08;20240829&#xff09;1 误区2 硬件3 操作系统4 数据库总结 数据库管理-第236期 数据库一体机的价值&#xff08;20240829&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff…

深入探索【Hadoop】生态系统:Hive、Pig、HBase及更多关键组件(上)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《大数据前沿&#xff1a;技术与应用并进》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Hadoop简介 2、Hadoop生态系统的构成概览 3、…

native 添加堆栈

第一种方法 montecarloh53b getVehicleModel:default error: frameworks/native/services/surfaceflinger/Android.bp:248:1: module "surfaceflinger" variant "android_arm64_armv8-a": depends on //system/unwinding/libbacktrace:libbacktrace which …

YarnClient发送和接收请求源码解析

YarnClient发送和接收请求流程 Yarn是通过RPC协议通信的&#xff0c;协议类型可以通过查看RpcKind类得知&#xff0c;总共有三种类型&#xff1a; RPC_BUILTIN ((short) 1), // Used for built in calls by tests RPC_WRITABLE ((short) 2), // Use WritableRp…