TMDS数据编码算法

TMDS,Transition Minimized Differential Signaling,即最小化差分传输信号,在DVI(数字视频接口,只能传输视频)和HDMI(音视频均可传输)协议中用于传输音视频数据,使用差分信号传输高速串行数据。

1、TMDS接口

TMDS连接从逻辑功能上可以划分成两个阶段:编码和并串转换。在编码阶段,编码器将视频源中的像素数据、HDMI的音频/附加数据,以及行同步和场同步信号分别编码成10位的字符流。然后在并串转换阶段将上述的字符流转换成串行数据流,并将其从三个差分输出通道发送出去。
在这里插入图片描述

2、TMDS算法

TMDS算法框图
在这里插入图片描述
TMDS通过逻辑算法将8bit字符数据通过最小转换编码为10bit字符数据,前8bit由原始信号通过运算获得,第9位表示运算的方式,1表示异或,0表示异或非。经过直流平衡后(第10位),采用差分信号传输数据。第10位是一个反转标志位,1表示反转,0表示没有反转,从而达到DC平衡。
接收端在收到信号后,再进行相反的运算。TMDS 和 LVDS、TTL 相比有较好的电磁兼容性能。这种算法可以减小传输信号过程的上冲和下冲,而 DC 平衡使信号对传输线的电磁干扰减少,可以用低成本的专用电缆实现长距离、高质量的数字信号传输。

3、TMDS逻辑代码

module Encoder(
    input                         i_pixel_clk     ,             //像素时钟
	input                         i_rst          ,             //复位信号,高有效
	input           [07:00]        i_data         ,             //输入8位数据
	input                         i_de          ,             //像素数据有效信号
	input                         i_ctrl_1        ,             //控制信号1
    input                         i_ctrl_2        ,             //控制信号2
    output     reg  [09:00]        o_data                      //输出10位数	
    );
//计算数据中1的个数  	
    reg            [02:00]         num_1_data;       //1的个数
    reg            [07:00]         data_temp1; 	     
    always@(posedge i_pixel_clk)	
	begin
        num_1_data <= i_data[7] + i_data[6] + i_data[5] + i_data[4] + i_data[3] + i_data[2] +    i_data[1] + i_data[0];
	    data_temp1 <= i_data;
	end
//判断条件1	 8bit转变成9bit,减少跳变沿
	wire                          decision1;  
    wire           [08:00]        q_m;	
	assign  decision1 = (num_1_data > 3'd4) | ((num_1_data == 3'd4) & (data_temp1[0] == 0));    
	assign  q_m[0] = data_temp1 [0];	
	assign  q_m[1] = decision1 ? (q_m[0] ^ (~ data_temp1 [1])) : (q_m[0] ^ data_temp1[1]);
	assign  q_m[2] = decision1 ? (q_m[1] ^ (~ data_temp1 [2])) : (q_m[1] ^ data_temp1[2]);
	assign  q_m[3] = decision1 ? (q_m[2] ^ (~ data_temp1 [3])) : (q_m[2] ^ data_temp1[3]);
	assign  q_m[4] = decision1 ? (q_m[3] ^ (~ data_temp1 [4])) : (q_m[3] ^ data_temp1[4]);
	assign  q_m[5] = decision1 ? (q_m[4] ^ (~ data_temp1 [5])) : (q_m[4] ^ data_temp1[5]);
	assign  q_m[6] = decision1 ? (q_m[5] ^ (~ data_temp1 [6])) : (q_m[5] ^ data_temp1[6]);
	assign  q_m[7] = decision1 ? (q_m[6] ^ (~ data_temp1 [7])) : (q_m[6] ^ data_temp1[7]);
	assign  q_m[8] = decision1 ? 1'b0 : 1'b1;	
//计算q_m中1的个数和0的个数	
    reg            [03:00]         num_1_q_m;
    reg            [03:00]         num_0_q_m;    
	always@(posedge i_pixel_clk)
	begin
       num_1_q_m <= q_m[7] + q_m[6] + q_m[5] + q_m[4] + q_m[3] + q_m[2] + q_m[1] +     q_m[0];
       num_0_q_m <= 4'd8 - (q_m[7] + q_m[6] + q_m[5] + q_m[4] + q_m[3] + q_m[2] + q_m[1] + q_m[0]);
	end
    parameter      CTRLTOKEN0      =   10'b11_0101_0100;
    parameter      CTRLTOKEN1      =   10'b00_1010_1011;
    parameter      CTRLTOKEN2      =   10'b01_0101_0100;
    parameter      CTRLTOKEN3      =   10'b10_1010_1011;	
    reg                            de_temp1;
	reg                            de_temp2;
	reg                            ctrl_1_temp1;
	reg                            ctrl_1_temp2;   	
	reg                            ctrl_2_temp1;
	reg                            ctrl_2_temp2;
    reg            [08:00]         q_m_temp;	
//流水线时钟对齐,i_data已延迟一个时钟,其余延迟两个时钟后输出
    always@(posedge i_pixel_clk)
	begin
	   de_temp1 <= i_de;
	   de_temp2 <= de_temp1;
	   
	   ctrl_1_temp1 <= i_ctrl_1;
	   ctrl_1_temp2 <= ctrl_1_temp1;
	   
	   ctrl_2_temp1 <= i_ctrl_2;
	   ctrl_2_temp2 <= ctrl_2_temp1;
	   
	   q_m_temp <= q_m;
	end
//    1、cnt=0时表示上次传输无数据流极性差异
//    2、cnt>0,即cnt[4]=0表示上次数据流中传输了更多的1
//    3、cnt<0,即cnt[4]=1表示上次数据流中传输了更多的0	
    wire                           decision2;
    wire                           decision3;
    reg            [04:00]         cnt;
// cnt=0时表示上次传输无数据流极性差异
	assign    decision2  = (cnt == 5'd0) | (num_1_q_m == num_0_q_m);
    assign    decision3  = ((~cnt[4]) & (num_1_q_m > num_0_q_m)) | (cnt[4] & (num_1_q_m < num_0_q_m));
	always@(posedge i_pixel_clk or posedge i_rst)
	begin
       if(i_rst)
 	      begin
		    o_data <= 10'd0;
		    cnt <= 5'd0;
		  end
	   else begin
	         if(de_temp2)
	          begin
			   if(decision2)
			      begin
				  o_data[9] <= ~q_m_temp[8];
				  o_data[8] <= q_m_temp[8];
				  o_data[07:00] <= q_m_temp[8] ? q_m_temp[07:00] : (~q_m_temp[07:00]);
                  cnt <= q_m_temp[8] ? (cnt + num_1_q_m - num_0_q_m) : (cnt + num_0_q_m - num_1_q_m);
				  end
			   else begin 
			          if(decision3)
			            begin
				        o_data[9] <= 1'b1;
			            o_data[8] <= q_m_temp[8];
						o_data[07:00] <= ~q_m_temp[07:00];
			            cnt <= cnt + 2*q_m_temp[8] + num_0_q_m - num_1_q_m;
			            end
					  else begin
					       o_data[9] <= 1'b0;
						   o_data[8] <= q_m_temp[8];
					       o_data[07:00] <= q_m_temp[07:00];
						   cnt <= cnt - 2*(~q_m_temp[8]) + num_1_q_m - num_0_q_m;
						   end
			   end
			end
	    else begin
			    case({ctrl_2_temp2,ctrl_1_temp2})
			            2'b00 : o_data <= CTRLTOKEN0;
			            2'b01 : o_data <= CTRLTOKEN1;
			            2'b10 : o_data <= CTRLTOKEN2;	 		   
			            2'b11 : o_data <= CTRLTOKEN3;			   
			    endcase
	    cnt <= 5'd0;
			   end				   
		end
	end	
endmodule
  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小灰灰的FPGA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值