企业做网站公司有哪些重庆百度
在DisplayPort 1.4协议中,为了减少EMI,在8B/10B编码之前,需进行扰码Scramble。扰码用到了16-bit LFSR,表达式如下。
LFSR每移位8个bit后,用最高有效 8 位以相反的位顺序与一个字节数据进行异或从而实现数据加扰/解扰。如果数据是K码,则不进行异或,直接输出K码数据。
具体实现框图如下图。
当数据为SR符号(K28.0)时,需对LFSR进行复位,复位后寄存器初始值为FFFFh,如果时EDP,则复位初始值为FFFEh。
在DP1.4协议的附录E中,有用C代码实现8bit移位后并行输出的LFSR以及扰码输出的参考。
以此参考,我们可以用verilog实现数据位宽为8bit的扰码模块。
module scramble
( input I_rst_n ,//低有效input I_sr_rst ,input I_clk ,input I_kcode ,input [7:0] I_data ,//并行数据输入output O_kcode , output [7:0] O_data //扰码输出
);
reg [15:0] sr8;
reg [7:0] scrm_byte0;//data[7:0] firstreg I_kcode_d1;always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) beginI_kcode_d1 <= 1'b0;endelsebeginI_kcode_d1 <= I_kcode;end
end//LFSR 并行结构,8次移位后
always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) sr8 <= 16'hffff ; //16'hfffe ;16'hffff ;else if(I_sr_rst)sr8 <= 16'hffff ; //16'hfffe ;16'hffff ;elsebegin sr8[ 0] <= sr8[ 8]; sr8[ 1] <= sr8[ 9]; sr8[ 2] <= sr8[10]; sr8[ 3] <= sr8[11] ^ sr8[ 8]; sr8[ 4] <= sr8[12] ^ sr8[ 9] ^ sr8[ 8]; sr8[ 5] <= sr8[13] ^ sr8[10] ^ sr8[ 9] ^ sr8[ 8]; sr8[ 6] <= sr8[14] ^ sr8[11] ^ sr8[10] ^ sr8[ 9]; sr8[ 7] <= sr8[15] ^ sr8[12] ^ sr8[11] ^ sr8[10]; sr8[ 8] <= sr8[ 0] ^ sr8[13] ^ sr8[12] ^ sr8[11]; sr8[ 9] <= sr8[ 1] ^ sr8[14] ^ sr8[13] ^ sr8[12]; sr8[10] <= sr8[ 2] ^ sr8[15] ^ sr8[14] ^ sr8[13]; sr8[11] <= sr8[ 3] ^ sr8[15] ^ sr8[14]; sr8[12] <= sr8[ 4] ^ sr8[15]; sr8[13] <= sr8[ 5]; sr8[14] <= sr8[ 6]; sr8[15] <= sr8[ 7]; end
end always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) scrm_byte0 <= 8'd0 ; else if(I_kcode == 1'b0)begin scrm_byte0[ 0] <= I_data[ 0] ^ sr8[15];scrm_byte0[ 1] <= I_data[ 1] ^ sr8[14];scrm_byte0[ 2] <= I_data[ 2] ^ sr8[13];scrm_byte0[ 3] <= I_data[ 3] ^ sr8[12]; scrm_byte0[ 4] <= I_data[ 4] ^ sr8[11];scrm_byte0[ 5] <= I_data[ 5] ^ sr8[10]; scrm_byte0[ 6] <= I_data[ 6] ^ sr8[ 9]; scrm_byte0[ 7] <= I_data[ 7] ^ sr8[ 8]; end elsescrm_byte0 <= I_data[7:0];
end assign O_kcode = I_kcode_d1;
assign O_data = scrm_byte0;endmodule
为了验证LFSR并行输出是否正确,我们根据框图用verilog实现串行移位的LFSR模块。可以对比每移位8个时钟周期后LFSR输出数据与扰码模块中LFSR每个时钟并行输出数据是否一致。可以从每次SR复位后数据开始比对。串行移位的LFSR模块代码如下。
module lfsr_serial
( input I_rst_n ,input I_sr_rst ,input I_clk ,output O_shift8clk,output [15:0] O_lfsr
);reg [15:0] lfsr;
reg [2:0] srcnt;always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) lfsr <= 16'hffff ; //16'hfffe ;16'hffff ;else if(I_sr_rst)lfsr <= 16'hffff ; //16'hfffe ;16'hffff ;elsebegin lfsr[ 0] <= lfsr[15]; lfsr[ 1] <= lfsr[ 0]; lfsr[ 2] <= lfsr[ 1]; lfsr[ 3] <= lfsr[ 2] ^ lfsr[15]; lfsr[ 4] <= lfsr[ 3] ^ lfsr[15];lfsr[ 5] <= lfsr[ 4] ^ lfsr[15]; lfsr[ 6] <= lfsr[ 5]; lfsr[ 7] <= lfsr[ 6]; lfsr[ 8] <= lfsr[ 7]; lfsr[ 9] <= lfsr[ 8]; lfsr[10] <= lfsr[ 9]; lfsr[11] <= lfsr[10]; lfsr[12] <= lfsr[11]; lfsr[13] <= lfsr[12]; lfsr[14] <= lfsr[13]; lfsr[15] <= lfsr[14]; end
end always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) srcnt <= 3'd0 ; else if(I_sr_rst)srcnt <= 3'd0 ; elsesrcnt <= srcnt + 1'b1;
end assign O_lfsr = lfsr;
assign O_shift8clk = (srcnt==3'd0) ? 1'b1 : 1'b0;endmodule
Modelsim仿真工程可从如下地址下载。https://download.csdn.net/download/cjie221/90593284
仿真波形如下。仿真结果与预期一致。
但实际应用中,数据位宽往往不是8bit,而是更宽的16bit或32bit,甚至64bit,这种情况扰码模块要更复杂一些,需多次迭代。