一.编码步骤:
基本方法:取第一位数据为初值,接下来输入的每一位与前一导出的位(根据判断条件)进行异或XOR或者同或XNOR(最小化传输,减少0/1翻转);最后选择性反转这9bit数据(DC平衡处理,平衡0和1的个数)。
①DE为高电平时,对8位RGB数据编码,第9bit表示采用了XOR / XNOR ,第10bit表示是否翻转。
②DE为低电平时,根据2bit的控制位(4种情况)输出10bit数据(固定4个值)。(直接使用查找表)。
知识点:一组数据中0的个数多,用异或可减少翻转次数
一组数据中1的个数多,用同或可减少翻转次数
例子如下:
二.编码流程:
三.代码设计
抛开流程图设计思想,只看图设计代码,这种类型的代码编码一般有一下流程:
①.先把输入的数据用寄存器打x拍,实现流水线对齐。
②.单独拎出所有三角形,用组合逻辑语句设计判决条件:
condition1 = ( 三角形内部语句 ) ? 1 : 0 ;
同理......
③.用时序逻辑按顺序根据条件编写输出。
//根据流程图写代码
//啥时候用组合啥时候用时序?判决条件用组合,打拍,输出用时序。输入经过打拍之后,后面其实可以根据需要使用组合逻辑
module TMDS_coder
(
input clk ,
input resetn ,
input d_e ,
input [7:0]d_in ,
input c0 ,
input c1 ,
output reg[9:0]d_out
);
reg [4:0]cnt ;//极性寄存器,计数器差距统计:统计 1 和 0 是否过量发送,最高位(cnt[4])是符号位
reg [7:0]d_in_reg ;//输入数据寄存器
wire [8:0]d_m ;//9bit寄存器
reg [3:0]numd1 ;//计数8bit中1的个数
reg [3:0]numd0 ;//计数8bit中0的个数
reg [3:0]numd_m1 ;//计数8bit中1的个数
reg [3:0]numd_m0 ;//计数8bit中0的个数
//控制信号输出查找表
parameter c1c0_00 = 10'b1101010100;
parameter c1c0_01 = 10'b0010101011;
parameter c1c0_10 = 10'b0101010100;
parameter c1c0_11 = 10'b1010101011;
//输入数据打一拍,统计输入的数据0和1的个数
always@(posedge clk)
begin
d_in_reg <= d_in ;
numd1 <= d_in_reg[0] + d_in_reg[1] + d_in_reg[2] + d_in_reg[3] + d_in_reg[4] + d_in_reg[5] + d_in_reg[6] + d_in_reg[7] ;
numd0 = 'd8 - ( d_in_reg[0] + d_in_reg[1] + d_in_reg[2] + d_in_reg[3] + d_in_reg[4] + d_in_reg[5] + d_in_reg[6] + d_in_reg[7] ) ;
end
//判定条件设计:
//知识点(经验):把流程图的判定条件用组合逻辑定义成一个变量(是/否 --> 1/0 ) (之前显示屏取范围亦是如此)
//状态机用的是时序逻辑,区别
wire condition1 ;//条件1
assign condition1 = (numd1 > 4 ) || ( (numd1 == 4 ) && ( d_in[0] == 0 ) ) ;
//这里用了组合逻辑赋值
assign d_m[0] = d_in_reg[0] ;
assign d_m[1] = (condition1) ? ~( d_m[0]^d_in_reg[1] ) : ( d_m[0]^d_in_reg[1] ) ;
assign d_m[2] = (condition1) ? ~( d_m[1]^d_in_reg[2] ) : ( d_m[1]^d_in_reg[2] ) ;
assign d_m[3] = (condition1) ? ~( d_m[2]^d_in_reg[3] ) : ( d_m[2]^d_in_reg[3] ) ;
assign d_m[4] = (condition1) ? ~( d_m[3]^d_in_reg[4] ) : ( d_m[3]^d_in_reg[4] ) ;
assign d_m[5] = (condition1) ? ~( d_m[4]^d_in_reg[5] ) : ( d_m[4]^d_in_reg[5] ) ;
assign d_m[6] = (condition1) ? ~( d_m[5]^d_in_reg[6] ) : ( d_m[5]^d_in_reg[6] ) ;
assign d_m[7] = (condition1) ? ~( d_m[6]^d_in_reg[7] ) : ( d_m[6]^d_in_reg[7] ) ;
assign d_m[8] = (condition1) ? 0 : 1 ;
//统计9bit寄存器中数据位0/1个数
always@(posedge clk)
begin
numd_m1 = d_m[0] + d_m[1] + d_m[2] + d_m[3] + d_m[4] + d_m[5] + d_m[6] + d_m[7] ;
numd_m0 = 'd8 - ( d_m[0] + d_m[1] + d_m[2] + d_m[3] + d_m[4] + d_m[5] + d_m[6] + d_m[7] ) ;
end
wire condition2 ;//条件2
assign condition2 = d_e ;
wire condition3 ;//条件3
assign condition3 = ( (cnt == 0 ) || ( (numd_m1) == ( numd_m0) ) ) ;
wire condition4 ;
assign condition4 = (d_m[8] == 0) ? 1 : 0 ;
wire condition5 ;//大于零小于零的问题怎么解决?教程用符号位解决,不知道cnt是怎么能算出来的。
assign condition5 = ( ((~cnt[4]) && (numd_m1 > numd_m0) ) || ( (cnt[4] ) && ( numd_m0 > numd_m1 ))) ;
/*如何统计1/0个数的多/少了几个,是设计角度的问题。为了D/C平衡(直流均衡),才做统计,流程处理,如果不做均衡可以不处理。
从代码的角度看,只需要知道cnt[4]是符号位就可以判断了。
*/
/*怎么样设计关联多次输入的变量cnt啊?
想法:设计一个输入一个输出,输出接到输入...
教程方法:本来就能存cnt值,只要不去刷新他
*/
reg [1:0]c0_reg ;
reg [1:0]c1_reg ;
reg [1:0]d_e_reg ;
reg [8:0]d_m_reg ;
//流水线对齐,打2拍,d_m输入时已经打一拍了,这里打一拍
always@(posedge clk)
begin
c0_reg <= {c0_reg[0],c0};
c1_reg <= {c1_reg[0],c1};
d_e_reg <= {d_e_reg[0] , d_e } ;
d_m_reg <= d_m ;
end
//设计输出
always@(posedge clk or negedge resetn )
if(!resetn)
begin
cnt <= 0 ;
d_out <= 0 ;
end
else
begin
if ( condition2 )
begin
if (condition3)
begin
d_out[9] <= ~d_m_reg[8] ;
d_out[8] <= d_m_reg[8] ;
d_out[7:0] <= (d_m_reg[8]) ? d_m_reg[7:0] : ~d_m_reg[7:0] ;
if(condition4)
begin
cnt <= cnt + ( numd_m0 - numd_m1 ) ;
end
else
begin
cnt <= cnt + ( numd_m1 - numd_m0 ) ;
end
end
else
begin
if(condition5)
begin
d_out[9] <= 1 ;
d_out[8] <= d_m_reg[8] ;
d_out[7:0] <= ~d_m_reg[7:0] ;
cnt <= cnt + ( d_m_reg[8] << 1 ) + ( numd_m0 - numd_m1 ) ;
end
else
begin
d_out[9] <= 0 ;
d_out[8] <= d_m_reg[8] ;
d_out[7:0] <= d_m_reg[7:0] ;
cnt <= cnt - ( d_m_reg[8] << 1 ) + ( numd_m1 - numd_m0 ) ;
end
end
end
else
begin
cnt <= 0 ;
case({c1_reg[0],c0_reg[0]})
2'b00 : d_out <= c1c0_00 ;
2'b01 : d_out <= c1c0_01 ;
2'b10 : d_out <= c1c0_10 ;
2'b11 : d_out <= c1c0_11 ;
endcase
end
end
endmodule
仿真结果:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)