TMDS编码原理以及Verilog实现HDMI接口

news2024/11/9 6:11:52

文章目录

  • 一、HDMI简介
  • 二、HDMI接口以及引脚定义
  • 三、HDMI传输原理
  • 四、TMDS编码规则以及实现
    • 4.1 TMDS编码框图
    • 4.2 TMDS编码流程图
    • 4.3 Verilog实现TMDS编码
  • 五、OSERDESE2原语介绍以及使用
    • 5.1 OSERDESE2内部框图
    • 5.2 OSERDESE2 输入输出管脚信号说明
    • 5.3 OSERDESE2 配置属性信号说明
    • 5.4 OSERDESE2 例化模板
    • 5.5 调用OSERDESE2级联原语
  • 六、HDMI发送系统框图


一、HDMI简介

  之前我们了解并且实现了VGA视频接口协议;VGA接口是早期使用的模拟视频接口,传输的是模拟信号。但是随着电子设备集成度越来越高,视频分辨率越来越高,VGA已经不能满足需求,因此视频接口发展到现在,HDMI接口成为了主流。
  HDMI(High-Definition Multimedia Interface)是一种高清多媒体接口,它是一种全数字的音视频传输接口,用于连接各种音视频设备,如电视、显示器、音响系统、游戏机、电脑等。

  HDMI接口相对于VGA接口的一些主要优势:

  1. 数字信号传输:HDMI传输的是数字信号,而VGA传输的是模拟信号。数字信号在传输过程中更稳定,不易受干扰,能提供更清晰的图像质量。

  2. 高清视频支持:HDMI接口支持高清视频格式,如1080p、4K、8K等,而VGA接口最高仅支持到1080p,并且通常用于较低分辨率的视频传输。

  3. 音频传输:HDMI接口可以同时传输音频和视频信号,而VGA接口仅传输视频信号。这意味着使用HDMI接口时,不需要另外的音频线缆。

  4. 双向通信:HDMI接口支持CEC(Consumer Electronics Control)等双向通信协议,可以实现设备间的智能控制和交互,而VGA接口不支持。

  5. 接口体积小:HDMI接口比VGA接口体积小了许多,适合现在集成度越来越高的产品

二、HDMI接口以及引脚定义

  根据《HDMI协议规范1.4b》可知,一共有五种类型的接口:HDMI A Type、HDMI B Type、HDMI C Type、HDMI D Type、HDMI E Type。不同类型的HDMI接口使用范围不同,分别如下:
在这里插入图片描述

  1. A型:标准全尺寸HDMI接口,是日常生活中最常见的类型;广泛用于电视、电脑、投影仪、游戏机、蓝光播放器、AV接收器和许多其他消费电子设备。
  2. B型:支持双链路的接口,能够提供更高的带宽和分辨率;较少使用,主要针对高分辨率显示器和专业设备。
  3. C型:也称为Mini HDMI接口,体积比A型小,适用于需要节省空间的设备;常用于便携式设备如平板电脑、便携式摄像机、部分笔记本电脑和一些较小的高清摄像设备。
  4. D型:也称为Micro HDMI接口,比C型更小,适用于超便携设备;广泛用于智能手机、超薄平板电脑、小型摄像设备和其他超便携设备。
  5. E型:专为汽车内部使用设计,具有增强的锁定机制和抗震性;用于汽车信息娱乐系统、车载显示器和其他汽车电子设备。

  因为A型HDMI接口使用范围更广,因此本章只讲A型HDMI接口的实现,其中针脚分配如下:
在这里插入图片描述

引脚 定义 引脚 定义
1数据2+11时钟屏蔽
2数据2屏蔽12时钟-
3数据2-13CEC
4数据1+14保留
5数据1屏蔽15DDC时钟线(SCL)
6数据1-16DDC数据线(SDA)
7数据0+17DDC/CEC地
8数据0屏蔽18+5V电源
9数据0-19热插拔检测
10时钟+
  • TMDS通道:引脚1 ~ 引脚12,负责发送音频、视频及各种辅助数据;
  • DDC通道:引脚15、16、17。DDC全文为Display Data Channel,发送端与接收端可利用 DDC 沟道得知彼此的发送与接收能力,但 HDMI 仅需单向获知接收端(显示器)的能力;DDC 通道使用 100kHz 时钟频率的 I²C 信号,发送数据结构为EDID。
  • CEC通道:引脚13、17。CEC通道为必须预留线路,但可以不必实现,作用是用来发送工业规格的 AV Link 协议信号。
  • 其他通道:引脚14位保留引脚,无连接;引脚18为+5V电源;引脚19位热插拔检测引脚。

三、HDMI传输原理

  HDMI的系统架构有发射源和接收器组成,给定的设备可能有一个或以上HDMI输入和一个或以上的 HDMI输出。所有的 HDMI输入都要满足 HDMI 接收器的规则,所有的 HDMI输出都要满足 HDMI发射器的规则。系统架构如下:

在这里插入图片描述
  如图所示,HDMI 发送器和接收器有四个差分线对组成TMDS数据通道和时钟通道,这些通道用于传递视频,音频和辅助数据,TMDS时钟通道始终发送与 TMDS 数据通道上的像素数据相一致的采样时钟;另外, HDMI 提供一个DDC 通道,DDC 是用于配置和在一个单独的信源端和一个单独的接收端交换状态;可选择的 CEC 在用户的各种不同的音视频产品中, 提供高水平的控制功能; 可选择的 HDMI 以太网和音频返回(HEAC),在连接的设备中提供以太网兼容的网络数据和一个和 TMDS 相对方向的音频回返通道;此外还有热插拔检测信号 HDP,当显示器等 HDMI 接口的显示设备通过 HDMI 接口与 HDMI 信源端相连或断开连接时,HDMI 信源端能够通过 HPD 引脚检测出这一事件,并做出响应。

四、TMDS编码规则以及实现

4.1 TMDS编码框图

在这里插入图片描述
  分对8bit的R、G、B数据编码,输出串行的差分信号。行场同步信号H,VSYNC作为B通道的控制信号也进行编码。4位的音频信号也同步编码(本文没有讲解音频编码,因此可以忽略)。

4.2 TMDS编码流程图

在这里插入图片描述

D 待编码的8bit视频信号
DE视频数据有效信号
C0,C1控制信号
N1{X}数据X中1的个数
N0{X}数据X中0的个数
q_out编码后的数据输出

  由流程图可以知道,第一个判断框通过判断输入数据中1的个数然后对数据进行异或编码,或者异或非编码成9位数据。第二第三个判断框再根据编码后qm中0 和1的个数再次编码来保证直流均衡。

4.3 Verilog实现TMDS编码

  根据TMDS编码流程图编写Verilog代码,注意时序对齐的问题。

`timescale 1ns / 1ns
module TMDS_encode(
    input                                               sys_clk,        //输入系统时钟
    input                                               sys_rstn,       //系统复位
    input                                               c0  ,           //控制信号c0
    input                                               c1  ,           //控制信号c1
    input                                               de  ,           //数据有效信号
    input           [7:0]                               data_in ,       //8bit像素
    output  reg     [9:0]                               data_out    	//编码后的10bit数据
);

//定义输入控制信号时,输出的数据
    parameter                                           CTRLTOKEN0  = 10'b1101010100;   
    parameter                                           CTRLTOKEN1  = 10'b0010101011; 
    parameter                                           CTRLTOKEN2  = 10'b0101010100; 
    parameter                                           CTRLTOKEN3  = 10'b1010101011; 


// 第一级流水线信号
    reg             [3:0]                               n1_din  ;       //统计输入8bit数据中1的个数
    reg             [7:0]                               data_in_d1  ;   
    reg                                                 de_d1   ;
    reg                                                 c0_d1   ;
    reg                                                 c1_d1   ;
    wire                                                decision1   ;   //第一个判断条件
    wire            [8:0]                               q_m ;           //第一级流水线输出的中间值
//第二级流水线信号
    reg             [3:0]                               n1_qm  ;        //统计qm中1的个数
    reg             [3:0]                               n0_qm  ;        //统计qm中0的个数
    wire                                                decision2   ;   //第二个判断条件
    wire                                                decision3   ;   //第三个判断条件
    reg             [4:0]                               cnt ;   		//视差计数器,之前编码后数据0-1个数差别,最高位为符号位
    reg             [8:0]                               qm_d1  ;   
    reg                                                 de_d2   ;
    reg                                                 c0_d2   ;
    reg                                                 c1_d2   ;

//处理第一级流水线
always @(posedge sys_clk or negedge sys_rstn) begin
    if(sys_rstn == 1'b0)
        n1_din <= 4'd0;
    else
        n1_din <= data_in[0] + data_in[1] + data_in[2] + data_in[3] + data_in[4] + data_in[5] + data_in[6] + data_in[7];
end

always @(posedge sys_clk) begin
    data_in_d1 <= data_in;
    de_d1 <= de;
    c0_d1 <= c0;
    c1_d1 <= c1;
end

assign decision1 = (n1_din > 4'd4) || ((n1_din == 4'd4)&&(data_in_d1[0] == 1'b0));

assign q_m[0] = data_in_d1[0];
assign q_m[1] = (decision1) ? (q_m[0] ^~ data_in_d1[1]):(q_m[0] ^ data_in_d1[1]);
assign q_m[2] = (decision1) ? (q_m[1] ^~ data_in_d1[2]):(q_m[0] ^ data_in_d1[1]);
assign q_m[3] = (decision1) ? (q_m[2] ^~ data_in_d1[3]):(q_m[0] ^ data_in_d1[1]);
assign q_m[4] = (decision1) ? (q_m[3] ^~ data_in_d1[4]):(q_m[0] ^ data_in_d1[1]);
assign q_m[5] = (decision1) ? (q_m[4] ^~ data_in_d1[5]):(q_m[0] ^ data_in_d1[1]);
assign q_m[6] = (decision1) ? (q_m[5] ^~ data_in_d1[6]):(q_m[0] ^ data_in_d1[1]);
assign q_m[7] = (decision1) ? (q_m[6] ^~ data_in_d1[7]):(q_m[0] ^ data_in_d1[1]);
assign q_m[8] = (decision1) ? 1'b0:1'b1;

//处理第二级流水线
always @(posedge sys_clk or negedge sys_rstn) begin
    if(sys_rstn == 1'b0)begin
        n1_qm <= 4'd0;
        n0_qm <= 4'd0;
    end
    else begin
        n1_qm <= q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
        n0_qm <= 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
end

always @(posedge sys_clk) begin
    qm_d1 <= q_m;
    de_d2 <= de_d1;
    c0_d2 <= c0_d1;
    c1_d2 <= c1_d1;
end

assign decision2 = (cnt == 5'd0) || (n1_qm == n0_qm);
//decision3中通过符号位判断cnt是否大于0
assign decision3 = ((~cnt[4] == 1'b1) && (n1_qm > n0_qm)) || ((cnt[4] == 1'b1) && (n1_qm < n0_qm));

always @(posedge sys_clk or negedge sys_rstn) begin
    if(sys_rstn == 1'b0)begin
        cnt <= 5'd0;
        data_out <= 10'd0;
    end
    else begin
        if(de_d2 == 1'b1)begin
            if(decision2 == 1'b1)begin
                data_out[9] <= ~ qm_d1[8];
                data_out[8] <= qm_d1[8];
                data_out[7:0] <= (qm_d1[8]) ? (qm_d1[7:0]) : (~qm_d1[7:0]);
                cnt <= (qm_d1[8]) ? (cnt + n0_qm - n1_qm) : (cnt + n1_qm - n0_qm);
            end
            else begin
                if(decision3 == 1'b1)begin
                    data_out[9] <= 1'b1;
                    data_out[8] <= qm_d1[8];
                    data_out[7:0] <= ~qm_d1[7:0];
                    cnt <= cnt + {qm_d1[8],1'b0} + n0_qm - n1_qm;
                end
                else begin
                    data_out[9] <= 1'b0;
                    data_out[8] <= qm_d1[8];
                    data_out[7:0] <= qm_d1[7:0];
                    cnt <= cnt - {~qm_d1[8],1'b0} + n1_qm - n0_qm;
                end
            end
        end
        else begin
            cnt <= 5'd0;
            case ({c1_d2,c0_d2})
                2'b00: data_out <= CTRLTOKEN0;
                2'b01: data_out <= CTRLTOKEN1;
                2'b10: data_out <= CTRLTOKEN2;
                default: data_out <= CTRLTOKEN3;
            endcase
        end
    end
end

endmodule

五、OSERDESE2原语介绍以及使用

  由于TMDS编码后的是10bit并行数据,而实际HDMI传输的是串行差分信号。因此需要将10bit编码后的数据转换成串行数据,再转换成差分信号,这里并转串使用的是Xilinx提供的OSERDESE2原语 。
  OSERDESE2 原语是 Xilinx 7 系列 FPGA 中的一种并行到串行转换器(Parallel-to-Serial Converter),能够在源同步接口中高效地将并行数据转换为串行数据。

  • 支持单数据速率(SDR)和双数据速率(DDR)模式。在 DDR 模式下,数据可以在每个时钟周期的上升沿和下降沿传输,从而实现数据传输速率的翻倍。
  • OSERDESE2 可以处理从 2 到 8 位的并行数据输入,并将其转换为串行输出。在某些情况下,可以通过宽度扩展(Width Expansion)技术,使用两个 OSERDESE2 模块来支持更大的数据宽度,如 10 位或 14 位。
  • OSERDESE2 使用两个时钟信号,CLK 和 CLKDIV。CLK 是高速串行时钟,而 CLKDIV 是分频后的并行时钟。这两个时钟信号必须在相位上对齐。

5.1 OSERDESE2内部框图

  OSERDESE2原语输入输出端口如下:

在这里插入图片描述

  OSERDESE2原语内部框图如下:
在这里插入图片描述
  OSERDESE2原语通过级联的系统框图如下:

在这里插入图片描述

5.2 OSERDESE2 输入输出管脚信号说明

输入端口 输出端口
CLK并串转后的串行数据伴随时钟OFB输出反馈端口,结合使用原语ISERDESE2或者ODELAYE2的时候会用到
CLKDIVCLK时钟的分频,为并转串前并行数据的伴随时钟OB串行数据输出端口
D1-D8待转换的8位并行数据,可配置为 2 至 8 位。使用 SLAVE 模式下的第二个 OSERDES 可以支持大于 6 位(级联后最多 14 位)的位宽SHIFTOUT1/SHIFTOUT2级联输出信号,连接至MASTER的SHIFTIN1/SHIFTIN2端口
OCE高电平有效的时钟使能信号TBYTEOUT字节组三态输出至IOB
RST复位信号,只需CLKDIV 频域时序(与 CLKDIV 同步)一个周期的复位脉冲TFB发送到 ODELAYE2 的 OSERDES 模块的 3 态控制输出。使用时,此端口将 3 态并行到串行转换器的输出连接到 ODELAYE2 的控制/3 态输入
SHIFTIN1 /SHIFTIN2级联输入信号,用于扩展数据输入,连接至SLAVE的SHIFTOUT1/SHIFTOUT2TQ OSERDES 模块的 3 态控制输出。使用时,此端口将 3 态并行到串行转换器的输出连接到 IOB 的控制/3 态输入
T1-T4三态控制模块的输入端口可配置1,2,4位
TBYTEIN字节组三态输入
TCE高电平有效的3态控制模块时钟使能信号

5.3 OSERDESE2 配置属性信号说明

端口名称端口说明
DATA_RATE_OQ定义数据是以单倍数据速率 (SDR) 还是双倍数据速率 (DDR) 进行处理
DATA_RATE_TQ定义是否将三态控制处理为单数据速率 (SDR) 还是双数据速率 (DDR)
DATA_WIDTH定义并串转换器的并行数据输入宽度。此属性的可能值取决于 DATA_RATE_OQ 属性。当 DATA_RATE_OQ 设置为 SDR 时,DATA_WIDTH 属性的可能值为 2、3、4、5、6、7 和 8。当 DATA_RATE_OQ 设置为 DDR 时,DATA_WIDTH 属性的可能值为 4、6、8、10 和 14。当 DATA_WIDTH 设置为大于 8 的宽度时,必须将一对 OSERDES 配置为主从配置
INIT_OQ定义 OQ 输出的初始值
INIT_OQ定义 TQ 输出的初始值
SERDES_MODE定义使用宽度扩展时 OSERDES 模块是主模块还是从模块
SRVAL_OQ定义调用 SR 时OQ输出的值
SRVAL_TQ调用 SR 时 TQ 输出的值
TBYTE_CTL DDR3 模式启用三态 BYTE 操作。这允许三态信号从作为源的三态输出之一获取值
TBYTE_SRC启用 OSERDES 作为 DDR3 模式下三态字节操作的源
TRISTATE_WIDTH定义 3 态控制并串转换器的并行 3 态输入宽度。此属性的可能值取决于 DATA_RATE_TQ 属性。当 DATA_RATE_TQ 设置为 SDR 或 BUF 时,TRISTATE_WIDTH 属性只能设置为 1。 当 DATA_RATE_TQ 设置为 DDR 时,TRISTATE_WIDTH 属性的可能值为 4。 TRISTATE_WIDTH 不能设置为大于 4 的宽度。当 DATA_WIDTH 大于 4 时,请将 TRISTATE_WIDTH 设置为 1。

5.4 OSERDESE2 例化模板

  例化模板如下:

OSERDESE2 #(
      .DATA_RATE_OQ("DDR"),   // DDR, SDR
      .DATA_RATE_TQ("DDR"),   // DDR, BUF, SDR
      .DATA_WIDTH(4),         // Parallel data width (2-8,10,14)
      .INIT_OQ(1'b0),         // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ(1'b0),         // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE("MASTER"), // MASTER, SLAVE
      .SRVAL_OQ(1'b0),        // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ(1'b0),        // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL("FALSE"),    // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC("FALSE"),    // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH(4)      // 3-state converter width (1,4)
   )
   OSERDESE2_inst (
      .OFB(OFB),             // 1-bit output: Feedback path for data
      .OQ(OQ),               // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1(SHIFTOUT1),
      .SHIFTOUT2(SHIFTOUT2),
      .TBYTEOUT(TBYTEOUT),   // 1-bit output: Byte group tristate
      .TFB(TFB),             // 1-bit output: 3-state control
      .TQ(TQ),               // 1-bit output: 3-state control
      .CLK(CLK),             // 1-bit input: High speed clock
      .CLKDIV(CLKDIV),       // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1(D1),
      .D2(D2),
      .D3(D3),
      .D4(D4),
      .D5(D5),
      .D6(D6),
      .D7(D7),
      .D8(D8),
      .OCE(OCE),             // 1-bit input: Output data clock enable
      .RST(RST),             // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1(SHIFTIN1),
      .SHIFTIN2(SHIFTIN2),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1(T1),
      .T2(T2),
      .T3(T3),
      .T4(T4),
      .TBYTEIN(TBYTEIN),     // 1-bit input: Byte group tristate
      .TCE(TCE)              // 1-bit input: 3-state clock enable
   );

5.5 调用OSERDESE2级联原语

module oserdese2_10to1 (
    input                                               sys_rstn    ,   //系统复位
    input                                               clk ,           //并行数据时钟
    input                                               clk_5x  ,       //串行数据时钟,因为10位转1位,使用DDR模式所以是5倍并行时钟
    input           [9:0]                               data_in ,       //需要转换的10bit数据
    output                                              data_out        //转换后的串行数据
);
    
    wire                                                SLAVE_SHIFTOUT1   ;   //级联信号1
    wire                                                SLAVE_SHIFTOUT2   ;   //级联信号2


OSERDESE2 #(
      .DATA_RATE_OQ("DDR"),   // DDR, SDR :设置单倍速率或者双倍速率
      .DATA_RATE_TQ("SDR"),   // DDR, BUF, SDR
      .DATA_WIDTH(10),         // 并行数据位宽
      .INIT_OQ(1'b0),         // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ(1'b0),         // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE("MASTER"), // MASTER, SLAVE
      .SRVAL_OQ(1'b0),        // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ(1'b0),        // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL("FALSE"),    // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC("FALSE"),    // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH(1)      // 3-state converter width (1,4)
   )
   OSERDESE2_master (
      .OFB(),                   // 1-bit output: Feedback path for data
      .OQ(data_out),            // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1(),
      .SHIFTOUT2(),
      .TBYTEOUT(),              // 1-bit output: Byte group tristate
      .TFB(),                   // 1-bit output: 3-state control
      .TQ(),                    // 1-bit output: 3-state control
      .CLK(clk_5x),             // 1-bit input: High speed clock
      .CLKDIV(clk),             // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1(data_in[0]),
      .D2(data_in[1]),
      .D3(data_in[2]),
      .D4(data_in[3]),
      .D5(data_in[4]),
      .D6(data_in[5]),
      .D7(data_in[6]),
      .D8(data_in[7]),
      .OCE(1'b1),             // 1-bit input: Output data clock enable
      .RST(!sys_rstn),             // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1(SLAVE_SHIFTOUT1),
      .SHIFTIN2(SLAVE_SHIFTOUT2),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1(1'b0),
      .T2(1'b0),
      .T3(1'b0),
      .T4(1'b0),
      .TBYTEIN(1'b0),     // 1-bit input: Byte group tristate
      .TCE(1'b0)              // 1-bit input: 3-state clock enable
   );

   OSERDESE2 #(
      .DATA_RATE_OQ("DDR"),   // DDR, SDR :设置单倍速率或者双倍速率
      .DATA_RATE_TQ("SDR"),   // DDR, BUF, SDR
      .DATA_WIDTH(10),         // 并行数据位宽
      .INIT_OQ(1'b0),         // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ(1'b0),         // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE("SLAVE"), // MASTER, SLAVE
      .SRVAL_OQ(1'b0),        // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ(1'b0),        // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL("FALSE"),    // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC("FALSE"),    // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH(1)      // 3-state converter width (1,4)
   )
   OSERDESE2_slave (
      .OFB(),                   // 1-bit output: Feedback path for data
      .OQ(),            // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1(SLAVE_SHIFTOUT1),
      .SHIFTOUT2(SLAVE_SHIFTOUT2),
      .TBYTEOUT(),              // 1-bit output: Byte group tristate
      .TFB(),                   // 1-bit output: 3-state control
      .TQ(),                    // 1-bit output: 3-state control
      .CLK(clk_5x),             // 1-bit input: High speed clock
      .CLKDIV(clk),             // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1(1'b0),
      .D2(1'b0),
      .D3(data_in[8]),
      .D4(data_in[9]),
      .D5(1'b0),
      .D6(1'b0),
      .D7(1'b0),
      .D8(1'b0),
      .OCE(1'b1),                // 1-bit input: Output data clock enable
      .RST(!sys_rstn),          // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1(),
      .SHIFTIN2(),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1(1'b0),
      .T2(1'b0),
      .T3(1'b0),
      .T4(1'b0),
      .TBYTEIN(1'b0),     // 1-bit input: Byte group tristate
      .TCE(1'b0)              // 1-bit input: 3-state clock enable
   );

   // End of OSERDESE2_inst instantiation

endmodule

六、HDMI发送系统框图

  接下来把上面所有模块都用顶层文件调用起来,框图如下:

在这里插入图片描述

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

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

相关文章

如何写好AI绘画提示词?保姆级教程来了!

前言 提示词编辑是一个结构化的过程&#xff0c;用能被人类解释和理解的词语来描述图像&#xff0c;也就是告诉人工智能模型应该怎么绘制图片。 生成优质图像的秘诀 1.提示词要想编辑好&#xff0c;包括修饰词和好的句子结构&#xff0c;首先你要了解所有的修饰词类型。 2.St…

浅析Kubernetes的权限控制模型

Kubernetes是一个开源的容器编排引擎&#xff0c;用来对容器化应用进行自动化部署、扩缩和管理。它是一个强大的集群管理系统&#xff0c;提供了丰富的功能。他的一个核心组件是Kubernetes API Server&#xff0c;这是集群中所有资源管理的入口点&#xff0c;提供了一组RESTful…

【算能全国产AI盒子】基于BM1688CV186AH+FPGA智能物联工作站,支持差异化泛AI视觉产品定制

在数据呈现指数级增长的今天&#xff0c;越来越多的领域和细分场景对实时、高效的数据处理和分析的需求日益增长&#xff0c;对智能算力的需求也不断增强。为应对新的市场趋势&#xff0c;凭借自身的硬件研发优势&#xff0c;携手算能相继推出了基于BM1684的边缘计算盒子&#…

可视化大屏的C位:12种常见的情形,一文告诉你。

C位又称焦点图&#xff0c;是占据可视化大屏视觉焦点位置&#xff0c;一般位于屏幕最中间。本文先列举12个&#xff0c;供大家欣赏。 1.地球 2.世界地图 3.中国 4.行政区划 5.社区 6.园区 7.城市 8.场馆 9.建筑 10.工厂 11.设备 12.流程/组态

Excel 宏录制与VBA编程 —— 14、使用VBA处理Excel事件

简介 若希望特定事件处理程序在触发特定事件时运行&#xff0c;可以为 Application 对象编写事件处理程序。 Application 对象的事件处理程序是全局的&#xff0c;这意味着只要 Microsoft Excel 处于打开状态&#xff0c;事件处理程序将在发生相应的事件时运行&#xff0c;而不…

Spring Cloud Gateway3.x自定义Spring Cloud Loadbalancer负载均衡策略以及实现动态负载均衡策略的方案

目录 前言 1.原理分析 1.1 ReactiveLoadBalancerClientFilter源码分析 1.2 LoadBalancerClientFactory源码分析 2.代码实现 2.1 扩展原生RoundRobinLoadBalancer轮询策略 2.1.1 自定义实现RoundRobinLoadBalancer 2.1.2 配置自定义的RoundRobinLoadBalan…

【源码+文档+调试讲解】基于Java的推箱子游戏设计与实现

摘 要 社会在进步&#xff0c;人们生活质量也在日益提高。高强度的压力也接踵而来。社会中急需出现新的有效方式来缓解人们的压力。此次设计符合了社会需求&#xff0c;Java推箱子游戏可以让人们在闲暇之余&#xff0c;体验游戏的乐趣。具有操作简单,易于上手的特点。 推箱子…

Vulnhub靶场DC-4练习

目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 爆破登录2. 命令执行3. 反弹shell4. hydra爆破ssh5. 提权 0x04 总结 0x00 准备 下载链接&#xff1a;https://download.vulnhub.com/dc/DC-4.zip 介绍&#xff1a; DC-4 is another purposely built …

短视频矩阵系统搭建APP源码开发

前言 短视频矩阵系统不仅有助于提升品牌影响力和营销效率&#xff0c;还能帮助企业更精准地触达目标受众&#xff0c;增强用户互动&#xff0c;并利用数据分析来持续优化营销策略。 一、短视频矩阵系统是什么&#xff1f; 短视频矩阵系统是一种通过多个短视频平台进行内容创作…

汉语翻译藏语软件,这几款软件不妨一试!

在全球化日益加深的今天&#xff0c;语言障碍成为了许多人在文化交流、商务洽谈或旅游探险中不得不面对的问题。特别是对于汉语和藏语这两种语言来说&#xff0c;由于其独特的文化背景和语法结构&#xff0c;翻译起来更是难上加难。不过&#xff0c;好在科技的进步为我们带来了…

可变分区管理 分区分配算法

First Fit Algorithm Best Fit Algorithm FFA&#xff1a;按照起始地址从小到大&#xff08;本题为分区编号&#xff09;找到第一个能装下进程的起始地址填入第二个表 此时 原表中将起始地址进程大小 分区大小-进程大小 如此继续 BFA&#xff1a;按分区大小排序 从小到大 找到…

面试-synchronized(java5以前唯一)和ReentrantLock的区别

1.ReentrantLock&#xff08;再入锁&#xff09;&#xff1a; (1).在java.util.concurrent.locks包 (2).和CountDownLatch,FutureTask,Semaphore一样基于AQS实现。 AQS:AbstractQueuedSynchronizer 队列同步器。Java并发用来构建锁或其他同步主键的基础框架&#xff0c;是j.u.c…

vue3通过vue-video-player实现视频倍速、默认全屏、拖拽进度条等功能

效果图&#xff1a; 1、场景&#xff1a; js原生的video标签在不同浏览器及不同型号手机上都展示的不一样&#xff0c;一部分没有倍速&#xff0c;一部分没有全屏等功能&#xff0c;为了统一视频播放的交互功能&#xff0c;使用vue-video-player插件来完成&#xff0c;vue-vid…

3_电机的发展及学习方法

一、电机组成及发展 1、什么是励磁&#xff1f; 在电磁学中&#xff0c;励磁是通过电流产生磁场的过程。 发电机或电动机由在磁场中旋转的转子组成。磁场可以由 永磁体或励磁线圈产生。对于带有励磁线圈的机器&#xff0c;电流必须在线圈中流动才能产生&#xff08;激发&#x…

基于JSP的列车票务信息管理系统

开头语&#xff1a; 你好&#xff0c;我是专注于计算机科学与技术研究的学长。如果你对列车票务信息管理系统感兴趣或有相关需求&#xff0c;欢迎联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;IDE、数据库管理工具…

【java计算机毕设】网络教学平台java MySQL ssm vue html maven 项目设计 源代码+万字文档

目录 1项目功能 2项目介绍 3项目地址 1项目功能 【java计算机毕设】网络教学平台系统MySQL ssm vue html maven项目代码文档 小组作业 2项目介绍 系统功能&#xff1a; 网络教学平台系统包括管理员、学生、教师俩种角色。 管理员功能包括个人中心模块用于修改个人信息和密码…

HBDNY-40/1端子排电压继电器 DC110V 导轨安装 约瑟JOSEF

HBDNY系列端子排型电压电流继电器 系列型号&#xff1a;&#xff08;3、4过/低电压型&#xff0c;5、6过/低电流型&#xff09; HBDNY-30/1端子排型电压继电器&#xff1b;HBDNY-30/2端子排型电压继电器&#xff1b; HBDNY-30/3端子排型电压继电器&#xff1b;HBDNY-30/4端子…

芒果YOLOv10改进64:主干Backbone篇RepVGG结构:简单但功能强大的卷积神经网络架构

💡本篇内容:YOLOv10改进RepVGG结构:简单但功能强大的卷积神经网络架构 💡🚀🚀🚀本博客 改进源代码改进 适用于 YOLOv10 按步骤操作运行改进后的代码即可 💡本文提出改进 原创 方式:二次创新,YOLOv10 应部分读者要求,新增一篇RepVGG 论文理论部分 + 原创最…

AI视频教程下载-定制GPT:使用您的数据创建一个定制聊天GPT

Custom GPTs_ Create a Custom ChatGPT with Your Data 构建一个定制的GPT&#xff0c;与您自己的数据进行聊天。添加文档&#xff0c;生成图像&#xff0c;并集成API和Zapier。 这门全面的Udemy课程专为那些渴望学习如何创建自己定制版ChatGPT的人设计&#xff0c;以满足他们…

Java 面试笔记 | Java 基础:线程池

前言 在日常的工作学习生活中&#xff0c;用一种好的方法去学习&#xff0c;可以更加有效&#xff0c;比如费曼学习法&#xff1a;将学到的知识用自己的组织的语言表达出来&#xff0c;如果能够清晰明白的向别人解释清楚&#xff0c;那么就说明你是真的懂了&#xff0c;学会了…