当前位置: 首页 > news >正文

63.HDMI显示器驱动设计与验证-彩条实验

(1)常见的视频传输接口有三种: VGA 接口、 DVI 接口和 HDMI 接口,目前的显示设备都配有这三种视频传输接口。三类视频接口的发展历程为 VGA→DVI→HDMI。其中 VGA 接口出现最早,只能传输模拟图像信号; 随后出现的 DVI 接口又分为三类: DVI-A、 DVI-D、 DVI-I,分别可传输纯模拟图像信号、纯数字图像信号和兼容模拟、数字图像信号;最后的HDMI 在传输数字图像信号的基础上又可以传输音频信号。

(2)HDMI 全称“High Definition Multimedia Interface 高清多媒体接口”,HDMI 标准的制定,并没有抛弃 DVI 标准中相对成熟且较易实现的部分技术标准,整个传输原理依然是基于 TMDS 编码技术。针对 DVI 的诸多问题,HDMI 做了大幅改进。HDMI 接口体积更小,各种设备都能轻松安装可用于机顶盒、DVD 播放机、个人计算机、电视、游戏主机、综合扩大机、数字音响与电视机等设备;抗干扰能力更强,能实现最长20 米的无增益传输;针对大尺寸数字平板电视分辨率进行优化,兼容性好;拥有强大的版权保护机制(HDCP),有效防止盗版现象;支持 24bit 色深处理,(RGB、YCbCr4-4-4、YCbCr4-2-2);一根线缆实现数字音频、视频信号同步传输,有效降低使用成本和繁杂程度。

(3)HDMI type-a 引脚

TMDS:最小化传输差分信号

升腾A7板块采用了SII9134芯片,能实现VGA转HDMI的编码,因此不需要自己编写HDMI的编码

(4)如果要编写HDMI编码,对应Visio视图:

(5)TMDS编码(8bit转10bit)具体代码:

module encode
(input   wire                hdmi_clk        ,       input   wire                reset_n         ,       //复位信号,低电平有效input   wire                hsync           ,       //行同步信号input   wire                vsync           ,       //列同步信号input   wire                de              ,       input   wire        [7:0]   data_in         ,       output  reg         [9:0]   data_out           
);//变量定义
wire            condition_1     ;
wire            condition_2     ;
wire            condition_3     ;
wire    [8:0]   q_m             ;reg     [3:0]   q_m_n1          ;
reg     [3:0]   q_m_n0          ;
reg     [3:0]   data_in_n1      ;     //最多8个1 ,即1000 四位
reg     [7:0]   data_in_reg     ;
reg     [4:0]   cnt             ;
reg     [8:0]   q_m_reg         ;
reg             de_reg0         ;
reg             de_reg1         ;
reg             hsync_reg0      ;
reg             hsync_reg1      ;
reg             vsync_reg0      ;
reg             vsync_reg1      ;//条件定义
always@(posedge hdmi_clk or negedge reset_n)if(!reset_n)data_in_n1 <= 4'd0;else data_in_n1 <= data_in[0] + data_in[1] + data_in[2] + data_in[3]+data_in[4] + data_in[5] + data_in[6] + data_in[7];assign condition_1 = (data_in_n1 > 4'd4) || ((data_in_n1 == 4'd4) && (data_in_reg[0] == 1'd0));always@(posedge hdmi_clk or negedge reset_n)if(!reset_n)beginq_m_n1 <=  4'd0;q_m_n0 <=  4'd0;endelse beginq_m_n1   =   q_m[0] + q_m[1] + q_m[2] + q_m[3]+ q_m[4] + q_m[5] + q_m[6] + q_m[7];q_m_n0   =   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]);endassign condition_2 = (cnt == 5'd0)  ||  (q_m_n1 == q_m_n0);
assign condition_3 = ((cnt[4] == 1'd0) && (q_m_n1 > q_m_n0)) || ((cnt[4] == 1'd1) && (q_m_n1 < q_m_n0)); //打拍变量定义
always@(posedge hdmi_clk or negedge reset_n)if(!reset_n)begindata_in_reg <= 8'd0;q_m_reg     <= 9'd0;de_reg0     <= 1'd0;de_reg1     <= 1'd0;hsync_reg0  <= 1'd0;hsync_reg1  <= 1'd0;vsync_reg0  <= 1'd0;vsync_reg1  <= 1'd0;       endelse begin data_in_reg <= data_in;q_m_reg     <= q_m  ;de_reg0     <= de;de_reg1     <= de_reg0;hsync_reg0  <= hsync;hsync_reg1  <= hsync_reg0;vsync_reg0  <= vsync;vsync_reg1  <= vsync_reg0;     end//q_m信号变量
assign q_m[0]   =   data_in_reg[0]  ;
assign q_m[1]   =   condition_1 ? (q_m[0] == data_in_reg[1]) : (q_m[0] ^ data_in_reg[1]);
assign q_m[2]   =   condition_1 ? (q_m[1] == data_in_reg[2]) : (q_m[1] ^ data_in_reg[2]);
assign q_m[3]   =   condition_1 ? (q_m[2] == data_in_reg[3]) : (q_m[2] ^ data_in_reg[3]);
assign q_m[4]   =   condition_1 ? (q_m[3] == data_in_reg[4]) : (q_m[3] ^ data_in_reg[4]);
assign q_m[5]   =   condition_1 ? (q_m[4] == data_in_reg[5]) : (q_m[4] ^ data_in_reg[5]);
assign q_m[6]   =   condition_1 ? (q_m[5] == data_in_reg[6]) : (q_m[5] ^ data_in_reg[6]);
assign q_m[7]   =   condition_1 ? (q_m[6] == data_in_reg[7]) : (q_m[6] ^ data_in_reg[7]);
assign q_m[8]   =   condition_1 ? 1'd0 : 1'd1;always@(posedge hdmi_clk or negedge reset_n)if(!reset_n)begindata_out <= 10'd0;cnt      <= 5'd0;endelse beginif(de_reg1)beginif(condition_2)begindata_out[9] <= ~q_m_reg[8];data_out[8] <= q_m_reg[8];data_out[7:0] <= (q_m_reg[8]? q_m_reg[7:0]: ~q_m_reg[7:0]);if(q_m_reg[8] == 1'd0)cnt <= cnt + q_m_n0 - q_m_n1;else cnt <= cnt + q_m_n1 - q_m_n0;endelse beginif(condition_3)begindata_out[9] <= 1'd1;data_out[8] <= q_m_reg[8];data_out[7:0] <= ~q_m_reg[7:0];cnt <= cnt + {q_m_reg[8],1'd0} + q_m_n0 - q_m_n1;endelse begindata_out[9] <= 1'd0;data_out[8] <= q_m_reg[8];data_out[7:0] <= q_m_reg[7:0];cnt <= cnt - {~q_m_reg[8],1'd0} + q_m_n1 - q_m_n0;  endendendelse begincnt <= 5'd0;case({vsync_reg1,hsync_reg0})2'b00: data_out <= 10'b11_0101_0100;2'b01: data_out <= 10'b00_1010_1011;2'b10: data_out <= 10'b01_0101_0100;2'b11: data_out <= 10'b10_1010_1011;default:;endcaseendendendmodule

(6)原语:英文全称“Primitive”,是Xilinx针对其器件特征开发的一系列常用模块的名字,用户可以将其视为Xilinx公司为用户提供的库函数。原语按照功能可以分为10类,包括:计算组件、IO端口组件、寄存器和锁存器、时钟组件、处理器组件、移位寄存器组件、配置和检测组件、RAM/ROM组件、Slice/CLB组件以及G比特收发器组件。

(7)ODDR是Xilinx提供的双数据速率原语,双数据速率原语ODDR可以用于在逻辑资源中实现DDR寄存器,可以把单沿传输的数据转换为双沿传输的数据。

OBUFDA是Xilinx提供的将单端信号转换为差分信号的原语。

(8)升腾Pro对应Viso视图(驱动SII934芯片):

(9)对应代码:

  • IIC控制器
module IIC_ctrl(input   wire            clk         ,input   wire            reset_n     ,input   wire            IIC_start   ,input   wire            wr_en       ,input   wire            rd_en       ,input   wire    [7:0]   device_addr ,input   wire    [15:0]  byte_addr   ,input   wire    [7:0]   wr_data     ,input   wire            addr_num    ,output  reg             IIC_SCL     ,inout   wire            IIC_SDA     ,output  reg             IIC_clk     ,output  reg             IIC_end     ,output  reg     [7:0]   rd_data     );reg     [4:0]       cnt_1M          ;      //计数最大值是25  一个五位宽的寄存器足以胜任计数任务reg     [15:0]      state           ;reg     [1:0]       IIC_clk_cnt     ;reg                 EN_IIC_clk_cnt  ;reg     [2:0]       bit_cnt         ;reg                 ack             ;reg                 sda_out         ;reg     [7:0]       rd_data_reg     ;wire                sda_in          ;wire                EN_IIC_SDA      ;wire    [6:0]       device_add_i    ;   assign device_add_i = device_addr[7:1];parameter IDLE        =  16'b0000_0000_0000_0001    ;       //空闲状态parameter START       =  16'b0000_0000_0000_0010    ;       //发送开始信号parameter SEND_D_A    =  16'b0000_0000_0000_0100    ;       //发送控制命令(器件地址+写操作)   {7'b1010_011,1'b0}parameter ACK_1       =  16'b0000_0000_0000_1000    ;       //等待响应 parameter SEND_B_H    =  16'b0000_0000_0001_0000    ;       //发送存储地址高8位  parameter ACK_2       =  16'b0000_0000_0010_0000    ;       //等待响应parameter SEND_B_L    =  16'b0000_0000_0100_0000    ;       //发送存储地址低8位parameter ACK_3       =  16'b0000_0000_1000_0000    ;       //等待响应parameter WR_DATA     =  16'b0000_0001_0000_0000    ;       //写入单比特数据   parameter ACK_4       =  16'b0000_0010_0000_0000    ;       //等待响应parameter START_2     =  16'b0000_0100_0000_0000    ;       //发送开始信号parameter SEND_RD_A   =  16'b0000_1000_0000_0000    ;       //发送控制命令(器件地址+读操作)   {7'b0101_011,1'b1} parameter ACK_5       =  16'b0001_0000_0000_0000    ;       //等待响应parameter RD_DATA     =  16'b0010_0000_0000_0000    ;       //读出单比特数据parameter NO_ACK      =  16'b0100_0000_0000_0000    ;       //等待无响应信号parameter END         =  16'b1000_0000_0000_0000    ;       //结束单比特传输//    parameter DEVICE_ADD  =  7'b1010_011 ;                      //EEPROM器件地址设定/*-----------IIC_clk生成模块--------------------*/
//IIC_clk 频率要求1MHz,而系统时钟clk频率为50MHz,半个周期需要计数25次(5位寄存器)always@(posedge clk or negedge reset_n)if(!reset_n)cnt_1M <= 5'd0;else if(cnt_1M == 5'd24)cnt_1M <= 5'd0;else cnt_1M <= cnt_1M + 5'd1;always@(posedge clk or negedge reset_n)if(!reset_n)IIC_clk <= 1'd0;else if(cnt_1M == 5'd24)IIC_clk <= ~IIC_clk;else IIC_clk <= IIC_clk;/*----------------状态机设计-----------------------*/  always@(posedge IIC_clk or negedge reset_n)if(!reset_n)state <= IDLE;else begincase(state)IDLE      :if(IIC_start)state <= START;else state <= state;START     : if(IIC_clk_cnt == 2'd3)state <= SEND_D_A;else state <= state;           SEND_D_A  : if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))state <= ACK_1;else state <= state;ACK_1     : if((IIC_clk_cnt == 2'd3) && (ack == 1'd0) &&  (addr_num == 1'd1))state <= SEND_B_H;else if((IIC_clk_cnt == 2'd3) && (ack == 1'd0) && (addr_num == 1'd0))state <= SEND_B_L;else state <= state;  SEND_B_H  : if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))state <= ACK_2;else state <= state;ACK_2     : if((IIC_clk_cnt == 2'd3) && (ack == 1'd0))state <= SEND_B_L;else state <= state;  SEND_B_L  : if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))state <= ACK_3;else state <= state;ACK_3     : if((IIC_clk_cnt == 2'd3) && (ack == 1'd0) && (wr_en == 1'd1))state <= WR_DATA;else if((IIC_clk_cnt == 2'd3) && (ack == 1'd0) && (rd_en == 1'd1))state <= START_2;else state <= state;WR_DATA   : if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))state <= ACK_4;else state <= state;ACK_4     : if((IIC_clk_cnt == 2'd3) && (ack == 1'd0))state <= END;else state <= state; START_2   : if(IIC_clk_cnt == 2'd3)state <= SEND_RD_A;else state <= state; SEND_RD_A : if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))state <= ACK_5;else state <= state;ACK_5     : if((IIC_clk_cnt == 2'd3) && (ack == 1'd0))state <= RD_DATA;else state <= state; RD_DATA   : if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))state <= NO_ACK;else state <= state;NO_ACK    : if(IIC_clk_cnt == 2'd3)state <= END;else state <= state; END       : if((bit_cnt == 3'd3) && (IIC_clk_cnt == 2'd3))state <= IDLE;else state <= state;default   : state <= IDLE;endcase       end/*----------------IIC_clk_cnt 、 EN_IIC_clk_cnt设计-----------------------*/
always@(posedge IIC_clk or negedge reset_n)if(!reset_n)IIC_clk_cnt <= 2'd0;else if(!EN_IIC_clk_cnt) IIC_clk_cnt <= 2'd0;else IIC_clk_cnt <= IIC_clk_cnt + 2'd1;always@(posedge IIC_clk or negedge reset_n)if(!reset_n)EN_IIC_clk_cnt <= 1'd0;else if((state == END) && (bit_cnt == 3'd3) && (IIC_clk_cnt == 2'd3))EN_IIC_clk_cnt <= 1'd0;else if(IIC_start)EN_IIC_clk_cnt <= 1'd1;else EN_IIC_clk_cnt <= EN_IIC_clk_cnt;/*--------------------bit_cnt设计-----------------------*/
always@(posedge IIC_clk or negedge reset_n)if(!reset_n)bit_cnt <= 3'd0;else if((state == IDLE)||(state == START)||(state == ACK_1)||(state == ACK_2)||(state == ACK_3)||(state == ACK_4) ||(state == START_2)||(state == ACK_5)||(state == NO_ACK))bit_cnt <= 3'd0;else if((state == END) && (bit_cnt == 3'd3) && (IIC_clk_cnt == 2'd3))bit_cnt <= 3'd0;else if(IIC_clk_cnt == 2'd3)bit_cnt <= bit_cnt + 3'd1;else bit_cnt <= bit_cnt;/*--------------------ack 、 sda_in信号设计---------------------------*/
always@(*)begincase(state)ACK_1,ACK_2,ACK_3,ACK_4,ACK_5   : if(IIC_clk_cnt == 2'd0)ack <= sda_in   ;else ack <= ack      ;default                         : ack = 1'd1;endcaseendassign sda_in = IIC_SDA ;/*--------------------IIC_SCL设计-----------------------*/
always@(*)begincase(state)IDLE:IIC_SCL <= 1'd1;START:if(IIC_clk_cnt == 2'd3)IIC_SCL <= 1'd0;else IIC_SCL <= 1'd1;SEND_D_A,ACK_1,SEND_B_H,ACK_2,SEND_B_L,ACK_3,WR_DATA,ACK_4,START_2,SEND_RD_A,ACK_5,RD_DATA,NO_ACK:if((IIC_clk_cnt == 2'd1) || (IIC_clk_cnt == 2'd2))IIC_SCL <= 1'd1;else IIC_SCL <= 1'd0;END:if((bit_cnt == 3'd0) && (IIC_clk_cnt == 2'd0))IIC_SCL <= 1'd0;else IIC_SCL <= 1'd1;default:IIC_SCL <= 1'd1;endcaseend/*--------------------sda_out 、 rd_data_reg设计-----------------------*/
always@(*)begincase(state)IDLE        :beginsda_out <= 1'd1; rd_data_reg <= 8'd0;endSTART       :if(IIC_clk_cnt >= 2'd1)sda_out <= 1'd0; else sda_out <= 1'd1;SEND_D_A    :if(bit_cnt <= 3'd6)sda_out <= device_add_i[6 - bit_cnt];else sda_out <= 1'd0;ACK_1,ACK_2,ACK_3,ACK_4,ACK_5   :sda_out <= 1'd1;SEND_B_H    :  sda_out <= byte_addr[15-bit_cnt]; SEND_B_L    :  sda_out <= byte_addr[7-bit_cnt];     WR_DATA     :sda_out <= wr_data[7-bit_cnt];        START_2     :if(IIC_clk_cnt >= 2'd2)sda_out <= 1'd0; else sda_out <= 1'd1;   SEND_RD_A   :if(bit_cnt <= 3'd6)sda_out <= device_add_i[6 - bit_cnt];else sda_out <= 1'd1;                 RD_DATA     :beginsda_out <= 1'd1;if(IIC_clk_cnt == 2'd2)rd_data_reg[7 - bit_cnt] <=  sda_in;else    rd_data_reg <= rd_data_reg;endNO_ACK      :sda_out <= 1'd1;END         :if((bit_cnt == 3'd0) && (IIC_clk_cnt <= 2'd2))sda_out <= 1'd0;else sda_out <= 1'd1;default     :beginsda_out <= 1'd1;rd_data_reg <= rd_data_reg;endendcaseend/*--------------------rd_data设计-----------------------*/ 
always@(posedge IIC_clk or negedge reset_n)if(!reset_n)rd_data <= 8'd0;else if((state == RD_DATA) && (bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))rd_data <= rd_data_reg;else    rd_data <= rd_data;/*--------------------EN_IIC_SDA设计-----------------------*/ 
//EN_IIC_SDA信号为1,表示IIC_SDA输出;反之,EN_IIC_SDA信号为0,表示IIC_SDA作为输入.assign EN_IIC_SDA = ((state == IDLE) || (state == START) || (state == SEND_D_A) || (state == SEND_B_H) || (state == SEND_B_L) || (state == WR_DATA)|| (state == START_2) || (state == SEND_RD_A) || (state == NO_ACK)|| (state == END));/*--------------------IIC_SDA设计-----------------------*/ 
assign IIC_SDA = EN_IIC_SDA ? sda_out : 1'dz;/*--------------------IIC_end设计-----------------------*/ 
always@(posedge IIC_clk or negedge reset_n)if(!reset_n)IIC_end <= 1'd0;else if((state == END) && (bit_cnt == 3'd3) && (IIC_clk_cnt == 2'd3))IIC_end <= 1'd1;else IIC_end <= 1'd0;endmodule
  • 给SII9134寄存器配置的模块
    module hdmi_cfg
    (input   wire            cfg_clk     ,input   wire            reset_n     ,input   wire            cfg_end     ,output  reg             cfg_start   ,output  wire   [31:0]   cfg_data    ,output  reg             cfg_done);parameter NUM_REG   = 10'd4 ;
    parameter CNT_WAIT_MAX  = 10'd1023  ;reg     [9:0]   cnt_wait    ;
    reg     [9:0]   cnt_num     ;wire    [31:0]  cfg_data_reg[NUM_REG - 1'd1 : 0];assign cfg_data_reg[0] = {8'h72,16'h08,8'h35};
    assign cfg_data_reg[1] = {8'h72,16'h49,8'h00};
    assign cfg_data_reg[2] = {8'h72,16'h4a,8'h00};
    assign cfg_data_reg[3] = {8'h72,16'h2f,8'h00};always@(posedge cfg_clk or negedge reset_n)if(!reset_n)cnt_wait <= 10'd0;else if(cnt_wait == CNT_WAIT_MAX)cnt_wait <= cnt_wait;else cnt_wait <= cnt_wait + 10'd1;always@(posedge cfg_clk or negedge reset_n)if(!reset_n)cnt_num <= 10'd0;else if(cfg_end)cnt_num <= cnt_num + 10'd1;else cnt_num <= cnt_num  ;always@(posedge cfg_clk or negedge reset_n)if(!reset_n)cfg_start <= 1'd0;else if(cnt_wait == CNT_WAIT_MAX - 1'd1)cfg_start <= 1'd1;else if(cfg_end == 1'd1 && cnt_num < NUM_REG)cfg_start <= 1'd1;else cfg_start <= 1'd0;assign cfg_data = cfg_done ?  32'd0 : cfg_data_reg[cnt_num];always@(posedge cfg_clk or negedge reset_n)if(!reset_n)cfg_done <= 1'd0;else if(cfg_end == 1'd1 && cnt_num == NUM_REG)cfg_done <= 1'd1;else cfg_done <= cfg_done; endmodule
    
  • IIC顶层模块
    module hdmi_iic
    (input       wire                hdmi_clk        ,input       wire                reset_n         ,output      wire                hdmi_scl        ,inout       wire                hdmi_sda        
    );wire                IIC_start;
    wire                IIC_end;
    wire    [31:0]      cfg_data; 
    wire                cfg_clk;IIC_ctrl    IIC_ctrl_inst
    (.clk         (hdmi_clk          ),.reset_n     (reset_n           ),.IIC_start   (IIC_start         ),.wr_en       (1'd1              ),.rd_en       (),.device_addr (cfg_data[31:24]   ),.byte_addr   (cfg_data[23:8]    ),.wr_data     (cfg_data[7:0]     ),.addr_num    (1'd0              ),.IIC_SCL     (hdmi_scl          ),.IIC_SDA     (hdmi_sda          ),.IIC_clk     (cfg_clk           ),.IIC_end     (IIC_end           ),.rd_data     ()
    );hdmi_cfg    hdmi_cfg_inst
    (.cfg_clk     (cfg_clk           ),.reset_n     (reset_n           ),.cfg_end     (IIC_end           ),.cfg_start   (IIC_start         ),.cfg_data    (cfg_data          ),.cfg_done    ());endmodule
    
  • 彩条数据生成模块
module data_gen(input   [9:0]   hang        ,input   [9:0]   lie         ,input           hdmi_clk     ,input           reset_n     ,output  reg     [23:0]  data    
);
//定义最大行、列parameter HANG_MAX  = 640   ;parameter LIE_MAX   = 480   ;//定义颜色parameter RED       =   24'hff0000;parameter ORANGE    =   24'hffcc66;parameter YELLOW    =   24'hffff00;parameter GREEN     =   24'h33cc33;parameter CYAN      =   24'h00ffcc;parameter BLUE      =   24'h3333ff;parameter PUPPLE    =   24'hcc00cc;parameter BLACK     =   24'h000000;parameter WHITE     =   24'hffffff;parameter GRAY      =   24'hb2b2b2;//数据生成设计always@(posedge hdmi_clk or negedge reset_n)if(!reset_n)data <= BLACK   ;else if((hang >= 1) && (hang <= HANG_MAX/10))data <= RED     ;else if((hang > HANG_MAX/10) && (hang <= (HANG_MAX/10) * 2))data <= ORANGE  ;else if((hang > (HANG_MAX/10) * 2) && (hang <= (HANG_MAX/10) * 3))data <= YELLOW  ;else if((hang > (HANG_MAX/10) * 3) && (hang <= (HANG_MAX/10) * 4))data <= GREEN  ;else if((hang > (HANG_MAX/10) * 4) && (hang <= (HANG_MAX/10) * 5))data <= CYAN  ;else if((hang > (HANG_MAX/10) * 5) && (hang <= (HANG_MAX/10) * 6))data <= BLUE  ;else if((hang > (HANG_MAX/10) * 6) && (hang <= (HANG_MAX/10) * 7))data <= PUPPLE  ;else if((hang > (HANG_MAX/10) * 7) && (hang <= (HANG_MAX/10) * 8))data <= BLACK  ;else if((hang > (HANG_MAX/10) * 8) && (hang <= (HANG_MAX/10) * 9))data <= WHITE  ;else if((hang > (HANG_MAX/10) * 9) && (hang <= HANG_MAX))data <= GRAY   ;elsedata <= BLACK  ;endmodule
  • 顶层模块:
    module hdmi_colorbar
    (input   wire                clk             ,input   wire                reset_n         ,output  wire                hdmi_clk        ,output  wire                hdmi_reset_n    ,output  wire                hdmi_scl        ,inout   wire                hdmi_sda        ,output  wire    [23:0]      rgb_tft         ,output  wire                hsync           ,output  wire                vsync           ,output  wire                tft_DE  );wire            clk_25M ;
    wire            rst_n   ;
    wire            locked  ;
    wire    [9:0]   hang    ;
    wire    [9:0]   lie     ;
    wire    [23:0]  data    ;assign  rst_n = reset_n & locked    ;
    assign  hdmi_reset_n = rst_n        ;clk_gen clk_gen_inst
    (.clk_25M    (clk_25M    ),     // output clk_25M.clk_125M   (),    .reset      (~reset_n   ), .locked     (locked     ),       .clk_in1    (clk        )
    );    assign hdmi_clk = clk_25M;  data_gen   data_gen_inst
    (.hang        (hang      ),.lie         (lie       ),.hdmi_clk    (clk_25M   ),.reset_n     (rst_n     ),.data        (data      )    
    );tft_ctrl    tft_ctrl_inst
    (.hdmi_clk        (clk_25M       ),.reset_n         (rst_n         ),.data_in         (data          ),.hang            (hang          ),.lie             (lie           ),.hsync           (hsync         ),.vsync           (vsync         ),.rgb_tft         (rgb_tft       ),.tft_DE          (tft_DE        )
    );hdmi_iic    hdmi_iic_inst
    (.hdmi_clk        (clk_25M       ),.reset_n         (rst_n         ),.hdmi_scl        (hdmi_scl      ),.hdmi_sda        (hdmi_sda      ));endmodule
    

(10)实验现象:

相关文章:

63.HDMI显示器驱动设计与验证-彩条实验

&#xff08;1&#xff09;常见的视频传输接口有三种&#xff1a; VGA 接口、 DVI 接口和 HDMI 接口&#xff0c;目前的显示设备都配有这三种视频传输接口。三类视频接口的发展历程为 VGA→DVI→HDMI。其中 VGA 接口出现最早&#xff0c;只能传输模拟图像信号&#xff1b; 随后…...

安卓13设置删除网络和互联网选项 android13隐藏设置删除网络和互联网选项

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改4.1修改方法14.2修改方法25.编译6.彩蛋1.前言 有些客户不想让用户修改默认的网络配置,禁止用户进入里面调整网络相关的配置。 2.问题分析 像这个问题,我们有好几种方法去处理,这种需求一般…...

C++的6种构造函数

在 C 中&#xff0c;构造函数是一种特殊的成员函数&#xff0c;用于初始化类对象。在对象创建时自动调用&#xff0c;构造函数的主要作用是分配资源、初始化数据成员等。根据不同的功能和使用场景&#xff0c;C 提供了多种类型的构造函数&#xff1a; 1. 默认构造函数 (Defaul…...

【FE】NPM——概述

NPM基本使用 下载Node 老生常谈&#xff0c;选择LTS版本官网放这里&#xff1a;https://nodejs.cn/download/ 1.镜像配置&#xff1a;镜像源 镜像配置 依赖仓库&#xff1a;版本查看 //不确定仓库有哪些版本&#xff0c;列出指定包的所有版本 npm view <package-name&…...

Clipboard.js实现复制文本到剪贴板功能

一、Clipboard.js简介 Clipboard.js是一个轻量级的实现复制文本到剪贴板功能的JavaScript插件&#xff0c;该插件可以将输入框&#xff0c;文本域&#xff0c;DOM节点元素中的文本内容复制到剪贴板中。 官网地址&#xff1a;Clipboard.js 浏览器兼容性&#xff1a;兼容Chrome、…...

Harbor安装笔记

下载离线安装包 wget https://github.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgz 解压 tar -zxvf harbor-offline-installer-v2.11.1.tgz 复制一份配置文件出来&#xff0c;修改配置 cp harbor.yml.tmpl harbor.yml vim harbor…...

HTTP 1.0 2.0 3.0详解

HTTP HTTP全称超文本传输协议&#xff0c;是一种属于应用层的通信协议。它允许将超文本标记语言文档&#xff08;HTML&#xff09;从Web服务器传输到客户端的浏览器。 HTTP报文结构 请求报文结构 请求方法&#xff1a; GET&#xff1a;一般用来请求已被URI识别的资源&#x…...

Python操作TXT文本:从入门到精通

在数字化时代,文本处理成为了许多工作和项目的基础。Python作为一种强大且易学的编程语言,在文本处理方面展现出了无与伦比的优势。本文将通过举例的方式,向读者介绍如何使用Python来操作TXT文本,让您轻松掌握文本处理的精髓。 一、读取TXT文本内容 首先,我们需要学会如…...

开源 AI 智能名片 2+1 链动模式 S2B2C 商城小程序的数据运营策略与价值创造

一、引言 1.1 研究背景 在当今数字化时代&#xff0c;数据运营已成为企业发展的核心驱动力。开源 AI 智能名片 21 链动模式 S2B2C 商城小程序作为一种创新的营销工具&#xff0c;与数据运营紧密相连。该小程序通过集成人工智能、大数据分析等先进技术&#xff0c;能够实时收集…...

ip 地址查看cmd命令

ip 地址查看cmd命令 在不同的操作系统中&#xff0c;查看IP地址的命令可能会有所不同。以下是一些常见操作系统中查看IP地址的命令&#xff1a; Windows: 打开命令提示符&#xff08;CMD&#xff09;&#xff0c;然后输入 ipconfig 命令。 Linux/Unix: 打开终端&#xff0…...

力扣9.26

931. 下降路径最小和 给你一个 n x n 的 方形 整数数组 matrix &#xff0c;请你找出并返回通过matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始&#xff0c;并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列&#xff08;即…...

HT8731 内置自适应H类升压和防破音功能的10W D类及AB类音频功率放大器

1、特点 防削顶失真功能(防破音,Anti-Clipping Function, ACF) 免滤波器数字调制&#xff0c;直接驱动扬声器 输出功率 10W(VBAT4.2V,RL3Ω,THDN10%, fiN 1kHz) 6W(VBAT3.3~4.2V,RL4Ω,THDN<1%,20-20kHz 全频段) 3W (VBAT3.3~4.2V,RL8Ω, THDN<1%, 20- 20kHz 全频段 VB…...

webpack使用

一、简介 概述 本次使用webpack4进行构建打包 二、webpack 安装webpack、webpack-cli npm install webpack4.2.0 webpack-cli4.2.0 -D 三、loader 加载器概述 raw-loader&#xff1a;加载文件原始内容&#xff08;utf-8&#xff09; file-loader&#xff1a;把文件输出…...

高通Android 12 音量API设置相关代码

// 获取当前音量大小public static int getCurrentVolume(Context context) {AudioManager audioManager (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);return audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); // 使用 STREAM_MUSIC 作为示例…...

Qt开发第一讲

一、Qt项目里面有什么&#xff1f; 对各个文件的解释&#xff1a; Empty.pro文件 QT core gui # 要引入的Qt模块&#xff0c;后面学习到一些内容的时候可能会修改这里 #这个文件相当于Linux里面的makefile文件。makefile其实是一个非常古老的技术了。 #qmake搭配.pr…...

详细指南:如何有效解决Windows系统中msvcp140.dll丢失的解决方法

如果你在使用Windows系统时遇到“msvcp140.dll丢失”的错误提示&#xff0c;通常是因为你的计算机上缺少或损坏了msvcp140.dll文件。msvcp140.dll是Microsoft Visual C Redistributable包的一部分&#xff0c;许多应用程序和游戏需要它来正常运行。以下是几种解决msvcp140.dll丢…...

【RabbitMQ】幂等性、顺序性

幂等性 概述 幂等性是数学和计算机科学中某些运算的性质&#xff0c;他们可以被多次应用&#xff0c;而不会改变初始应用的结果。RabbitMQ的幂等性则是指同一条消息&#xff0c;多次消费&#xff0c;对系统的影响是相同的。 一般消息中间件的消息传输保障分为三个层级&#…...

FFmpeg源码:avio_skip函数分析

AVIOContext结构体和其相关的函数分析&#xff1a; FFmpeg源码&#xff1a;avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析 FFmpeg源码&#xff1a;read_packet_wrapper、fill_buffer函数分析 FFmpeg源码&#xff1a;avio_read函数分析 FFmpeg源码&#xff…...

Llama 3.1 技术研究报告-6

6 推理 我们研究了两种主要技术&#xff0c;以使 Llama 3 405B 模型的推理⾼效&#xff1a;(1) 流⽔线并⾏和 (2) FP8 量化。我们已经公开发布了我们的 FP8 量化实现。 6.1 流⽔线并⾏ 当使⽤ BF16 数字表⽰模型参数时&#xff0c;Llama 3 405B 不适合在装有 8 个 Nvidia H1…...

更新日志-Python OS

这么久没更新全是因为这段时间的事情很多&#xff0c;只能一点一点的更新代码&#xff0c;不过好在&#xff0c;也是成功更新出来啦&#xff01; 更新日志&#xff08;2024/9/29&#xff09; 代码全文更新&#xff0c;将所有的绝对路径替换为相对路径&#xff0c;这样在各位大…...

Chrome浏览器的C++内存管理技术揭秘

Chrome浏览器作为全球最流行的网络浏览器之一&#xff0c;其高效的内存管理技术功不可没。本文将深入探讨Chrome浏览器在C中的内存管理技术&#xff0c;并介绍如何通过调整网页加载时间、优化视频播放体验和解决谷歌浏览器占用CPU过高的问题来提升浏览器性能。 &#xff08;本…...

Redis --- redis事务和分布式事务锁

redis事务基本实现 Redis 可以通过 MULTI&#xff0c;EXEC&#xff0c;DISCARD 和 WATCH 等命令来实现事务(transaction)功能。 > MULTI OK > SET USER "Guide哥" QUEUED > GET USER QUEUED > EXEC 1) OK 2) "Guide哥"使用 MULTI命令后可以输入…...

SQL,将多对多的关联记录按行输出

数据库的Primary表和Secondary表有相同的结构&#xff0c;其中W、H、D是主键。Primary表&#xff1a;NameWHDPrimary item 1100500300Primary item 2100600300Primary item 3200500300Primary item 4100500300Primary item 5100600300Primary item 6200500300 Secondary表&…...

【SQL】筛选字符串与正则表达式

目录 语法 需求 示例 分析 代码 语法 SELECT column1, column2, ... FROM table_name WHERE condition; WHERE 子句用于指定过滤条件&#xff0c;以限制从数据库表中检索的数据。当你执行一个查询时&#xff0c;WHERE 子句允许你筛选出满足特定条件的记录。如果记录满…...

【Redis入门到精通五】Java如何像使用MySQL一样使用Redis(jedis安装及使用)

目录 Jedis 1.jedis是什么 2.jedis的安装配置 3.jedis的基础命令操作展示 1.set和get操作&#xff1a; 2.exists和del操作&#xff1a; 3.keys和type操作&#xff1a; 4. expire和ttl&#xff1a; Jedis Java 操作 redis 的客⼾端有很多&#xff0c;其中最知名的是 jedi…...

【 微信机器人+ AI 搭建】

摘要&#xff1a; 各种大模型已经出来好久了&#xff0c;各类app也已经玩腻了&#xff0c;接下来&#xff0c;就在考虑&#xff0c;怎么让大模型&#xff0c;利益最大化。 本人没有显著的家世&#xff0c;没有富婆包养&#xff0c;只能自己抽点时间&#xff0c;研究下技术&…...

VGG16网络介绍及代码撰写详解(总结1)

可以从本人以前的文章中可以看出作者以前从事的是嵌入式控制方面相关的工作&#xff0c;是一个机器视觉小白&#xff0c;之所以开始入门机器视觉的学习只要是一个idea&#xff0c;想把机器视觉与控制相融合未来做一点小东西。废话不多说开始正题。 摘要&#xff1a;本文是介绍V…...

多个excel表数据比对操作

多个excel表数据比对操作 本文主要使用两种方法进行比对,分别使用了openpyxl第三方库和pandas第三方库进行数据比对 两种方法优缺点: openpyxy: 优点:主要是处理xlsx的文件,里面方法简单,易懂 缺点:当数据量大的时候,速度很慢,之前我一条一条数据拿出来比较,两百多条…...

golang学习笔记32——哪些是用golang实现的热门框架和工具

推荐学习文档 golang应用级os框架&#xff0c;欢迎stargolang应用级os框架使用案例&#xff0c;欢迎star案例&#xff1a;基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识&#xff0c;这里有免费的golang学习笔…...

ZYNQ:开发环境搭建

资料下载 http://47.111.11.73/docs/boards/fpga/zdyz_qimxing(V2).html Vivado软件是什么&#xff1f; Vivado软件是Xilinx&#xff08;赛灵思&#xff09;公司推出的一款集成设计环境&#xff08;IDE&#xff09;&#xff0c;主要用于FPGA&#xff08;现场可编程门阵列&am…...

甘孜网站建设/东莞网站推广软件

转载于:https://www.cnblogs.com/xiaobiaomei/p/9216717.html...

合肥做公司网站一般多少钱/营销软文范例大全

原标题&#xff1a;【沙发管家】苹果手机,&#xff0c;iPad连接安卓智能电视投屏方法现在很多人对于安卓智能电视的投屏功能已经非常熟悉&#xff0c;使用安卓手机的用户&#xff0c;有很多办法可以直接连接电视进行投屏&#xff0c;但是&#xff0c;使用苹果设备直连安卓智能电…...

怀化网页/优化设计五年级下册语文答案

光标移动移动到单词的最前面&#xff1a;option ←移动到单词最末尾&#xff1a;option →将当前行代码移动到上一行&#xff1a;option ↑将当前行代码移动到下一行&#xff1a;option ↓移动到当前行最前面&#xff1a;cmd ←移动到当前行最末尾&#xff1a;cmd →花括…...

微信知彼网络网站建设/dw友情链接怎么设置

最近几年&#xff0c;在DDD的领域&#xff0c;我们经常会看到CQRS架构的概念。我个人也写了一个ENode框架&#xff0c;专门用来实现这个架构。CQRS架构本身的思想其实非常简单&#xff0c;就是读写分离。是一个很好理解的思想。就像我们用MySQL数据库的主备&#xff0c;数据写到…...

免费做调查的网站/培训机构退费法律规定

事件广播 简介 Laravel 5.1 之中新加入了事件广播的功能&#xff0c;作用是把服务器中触发的事件通过websocket服务通知客户端&#xff0c;也就是浏览器&#xff0c;客户端js根据接受到的事件&#xff0c;做出相应动作。本文会用简单的代码展示一个事件广播的过程。 依赖 redis…...

怎么盗取网站/培训机构招生方案

目录一 开启线程的两种方式#方式一from threading import Threadimport timedef sayhi(name):time.sleep(2)print(%s say hello %name)if name main:tThread(targetsayhi,args(egon,))t.start()print(主线程)方式二from threading import Threadimport timeclass Sayhi(Thread…...