DP扰码模块verilog仿真

发布于:2025-04-11 ⋅ 阅读:(34) ⋅ 点赞:(0)

  在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] first

reg        I_kcode_d1;

always@(posedge I_clk or negedge I_rst_n) 
begin 
    if(!I_rst_n) 
        begin
            I_kcode_d1 <= 1'b0;
        end
    else
        begin
            I_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    ;
    else
        begin 
            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 
    else
        scrm_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    ;
    else
        begin 
            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    ; 
    else
        srcnt <= 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,这种情况扰码模块要更复杂一些,需多次迭代。


网站公告

今日签到

点亮在社区的每一天
去签到