DP 32bit位宽数据扰码实现和仿真
关于DisplayPort 1.4协议中扰码用的16-bit LFSR的移位8个时钟周期后的输出表达式我们已经用迭代的方法推导过,那么移位32个时钟周期的输出表达式同样可以迭代32次推导出,或者将移位8个时钟的输出表达式迭代3次也可以得到。以下就是移位32个时钟周期的输出表达式。
R0 = b10 x b8 x b6 x b0
R1 = b11 x b9 x b7 x b1
R2 = b12 x b10 x b8 x b2
R3 = b13 x b11 x b10 x b9 x b8 x b6 x b3
R4 = b14 x b12 x b11 x b9 x b8 x b7 x b6 x b4
R5 = b15 x b13 x b12 x b9 x b7 x b6 x b5
R6 = b14 x b13 x b10 x b8 x b7 x b6 x b0
R7 = b15 x b14 x b11 x b9 x b8 x b7 x b1
R8 = b15 x b12 x b10 x b9 x b8 x b2 x b0
R9 = b13 x b11 x b10 x b9 x b3 x b1
R10 = b14 x b12 x b11 x b10 x b4 x b2 x b0
R11 = b15 x b13 x b12 x b11 x b5 x b3 x b1
R12 = b14 x b13 x b12 x b6 x b4 x b2
R13 = b15 x b14 x b13 x b7 x b5 x b3
R14 = b15 x b14 x b8 x b6 x b4
R15 = b15 x b9 x b7 x b5
根据上述表达式,我们可以实现32bit输入数据的扰码和解码。我们用示意图说明32bit数据扰码和8bit数据扰码的区别。8bit数据扰码,每个时钟输入数据位宽为8bit,LFSR输出为移位8个时钟周期后的输出表达式,然后根据DP协议规则按位异或输出,输出数据也是8bit,如下图。
32bit数据扰码,每个时钟输入数据位宽为32bit,LFSR需要有四组,分别是移位8个时钟周期后输出,移位16个时钟周期后的输出,移位24个时钟周期后的输出,移位32个时钟周期后的输出,再根据DP协议规则分别与32bit数据中的4个字节按位异或输出,输出数据为32bit,如下图。
加扰scramble模块中的LFSR采用按上述迭代32个时钟周期的输出表达式方式实现。一共四组LFSR,分别与32bit数据的4个字节相异或处理。但因为LFSR是移位32个时钟周期的输出表达式,所以只能利用不同的复位初始值来分别对应4个字节。注:此代码只是用于仿真,可以方便调整输出数据中SR符号的位置,实际模块中无此功能。
module scramble #
(parameter SEQUENCY = 2'd0 //output sequency, 0:{SR,xx,xx,xx}// 1:{xx,SR,xx,xx}// 2:{xx,xx,SR,xx}// 3:{xx,xx,xx,SR}
)
( input I_rst_n ,//low activeinput I_sr_rst ,input I_clk ,input [3:0] I_kcode ,input [31:0] I_data ,//low byte firstoutput [3:0] O_kcode , output [31:0] O_data //scramble
);//=====================
reg [15:0] sr8_0;
reg [15:0] sr8_1;
reg [15:0] sr8_2;
reg [15:0] sr8_3; reg [7:0] scrm_byte0;//data[7:0] first
reg [7:0] scrm_byte1;//data[15:8] second
reg [7:0] scrm_byte2;//data[23:16] third
reg [7:0] scrm_byte3;//data[31:24] forthreg [3:0] I_kcode_d1;reg [3:0] scrm_kcode_d1;
reg [3:0] scrm_kcode_d2;
reg [31:0] scrm_data_d1;
reg [31:0] scrm_data_d2;//====================
always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) beginI_kcode_d1 <= 4'b0;endelsebeginI_kcode_d1 <= I_kcode;end
end//=====================
//LFSR 并行结构,32次移位后
always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) sr8_0 <= 16'hffff ; //16'hfffe ;16'hffff ;else if(I_sr_rst)sr8_0 <= 16'hffff ; //16'hfffe ;16'hffff ;elsebegin sr8_0[ 0] <= sr8_0[10] ^ sr8_0[ 8] ^ sr8_0[ 6] ^ sr8_0[ 0]; sr8_0[ 1] <= sr8_0[11] ^ sr8_0[ 9] ^ sr8_0[ 7] ^ sr8_0[ 1]; sr8_0[ 2] <= sr8_0[12] ^ sr8_0[10] ^ sr8_0[ 8] ^ sr8_0[ 2]; sr8_0[ 3] <= sr8_0[13] ^ sr8_0[11] ^ sr8_0[10] ^ sr8_0[ 9] ^ sr8_0[ 8] ^ sr8_0[ 6] ^ sr8_0[ 3]; sr8_0[ 4] <= sr8_0[14] ^ sr8_0[12] ^ sr8_0[11] ^ sr8_0[ 9] ^ sr8_0[ 8] ^ sr8_0[ 7] ^ sr8_0[ 6] ^ sr8_0[ 4]; sr8_0[ 5] <= sr8_0[15] ^ sr8_0[13] ^ sr8_0[12] ^ sr8_0[ 9] ^ sr8_0[ 7] ^ sr8_0[ 6] ^ sr8_0[ 5]; sr8_0[ 6] <= sr8_0[14] ^ sr8_0[13] ^ sr8_0[10] ^ sr8_0[ 8] ^ sr8_0[ 7] ^ sr8_0[ 6] ^ sr8_0[ 0]; sr8_0[ 7] <= sr8_0[15] ^ sr8_0[14] ^ sr8_0[11] ^ sr8_0[ 9] ^ sr8_0[ 8] ^ sr8_0[ 7] ^ sr8_0[ 1]; sr8_0[ 8] <= sr8_0[15] ^ sr8_0[12] ^ sr8_0[10] ^ sr8_0[ 9] ^ sr8_0[ 8] ^ sr8_0[ 2] ^ sr8_0[ 0]; sr8_0[ 9] <= sr8_0[13] ^ sr8_0[11] ^ sr8_0[10] ^ sr8_0[ 9] ^ sr8_0[ 3] ^ sr8_0[ 1]; sr8_0[10] <= sr8_0[14] ^ sr8_0[12] ^ sr8_0[11] ^ sr8_0[10] ^ sr8_0[ 4] ^ sr8_0[ 2] ^ sr8_0[ 0]; sr8_0[11] <= sr8_0[15] ^ sr8_0[13] ^ sr8_0[12] ^ sr8_0[11] ^ sr8_0[ 5] ^ sr8_0[ 3] ^ sr8_0[ 1]; sr8_0[12] <= sr8_0[14] ^ sr8_0[13] ^ sr8_0[12] ^ sr8_0[ 6] ^ sr8_0[ 4] ^ sr8_0[ 2]; sr8_0[13] <= sr8_0[15] ^ sr8_0[14] ^ sr8_0[13] ^ sr8_0[ 7] ^ sr8_0[ 5] ^ sr8_0[ 3]; sr8_0[14] <= sr8_0[15] ^ sr8_0[14] ^ sr8_0[ 8] ^ sr8_0[ 6] ^ sr8_0[ 4]; sr8_0[15] <= sr8_0[15] ^ sr8_0[ 9] ^ sr8_0[ 7] ^ sr8_0[ 5]; end
end always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) sr8_1 <= 16'he817 ; //16'he917 ;16'he817 ;else if(I_sr_rst)sr8_1 <= 16'he817 ; //16'he917 ;16'he817 ;elsebegin sr8_1[ 0] <= sr8_1[10] ^ sr8_1[ 8] ^ sr8_1[ 6] ^ sr8_1[ 0]; sr8_1[ 1] <= sr8_1[11] ^ sr8_1[ 9] ^ sr8_1[ 7] ^ sr8_1[ 1]; sr8_1[ 2] <= sr8_1[12] ^ sr8_1[10] ^ sr8_1[ 8] ^ sr8_1[ 2]; sr8_1[ 3] <= sr8_1[13] ^ sr8_1[11] ^ sr8_1[10] ^ sr8_1[ 9] ^ sr8_1[ 8] ^ sr8_1[ 6] ^ sr8_1[ 3]; sr8_1[ 4] <= sr8_1[14] ^ sr8_1[12] ^ sr8_1[11] ^ sr8_1[ 9] ^ sr8_1[ 8] ^ sr8_1[ 7] ^ sr8_1[ 6] ^ sr8_1[ 4]; sr8_1[ 5] <= sr8_1[15] ^ sr8_1[13] ^ sr8_1[12] ^ sr8_1[ 9] ^ sr8_1[ 7] ^ sr8_1[ 6] ^ sr8_1[ 5]; sr8_1[ 6] <= sr8_1[14] ^ sr8_1[13] ^ sr8_1[10] ^ sr8_1[ 8] ^ sr8_1[ 7] ^ sr8_1[ 6] ^ sr8_1[ 0]; sr8_1[ 7] <= sr8_1[15] ^ sr8_1[14] ^ sr8_1[11] ^ sr8_1[ 9] ^ sr8_1[ 8] ^ sr8_1[ 7] ^ sr8_1[ 1]; sr8_1[ 8] <= sr8_1[15] ^ sr8_1[12] ^ sr8_1[10] ^ sr8_1[ 9] ^ sr8_1[ 8] ^ sr8_1[ 2] ^ sr8_1[ 0]; sr8_1[ 9] <= sr8_1[13] ^ sr8_1[11] ^ sr8_1[10] ^ sr8_1[ 9] ^ sr8_1[ 3] ^ sr8_1[ 1]; sr8_1[10] <= sr8_1[14] ^ sr8_1[12] ^ sr8_1[11] ^ sr8_1[10] ^ sr8_1[ 4] ^ sr8_1[ 2] ^ sr8_1[ 0]; sr8_1[11] <= sr8_1[15] ^ sr8_1[13] ^ sr8_1[12] ^ sr8_1[11] ^ sr8_1[ 5] ^ sr8_1[ 3] ^ sr8_1[ 1]; sr8_1[12] <= sr8_1[14] ^ sr8_1[13] ^ sr8_1[12] ^ sr8_1[ 6] ^ sr8_1[ 4] ^ sr8_1[ 2]; sr8_1[13] <= sr8_1[15] ^ sr8_1[14] ^ sr8_1[13] ^ sr8_1[ 7] ^ sr8_1[ 5] ^ sr8_1[ 3]; sr8_1[14] <= sr8_1[15] ^ sr8_1[14] ^ sr8_1[ 8] ^ sr8_1[ 6] ^ sr8_1[ 4]; sr8_1[15] <= sr8_1[15] ^ sr8_1[ 9] ^ sr8_1[ 7] ^ sr8_1[ 5]; end
end always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) sr8_2 <= 16'h0328 ; //16'h0311 ;16'h0328 ;else if(I_sr_rst)sr8_2 <= 16'h0328 ; //16'h0311 ;16'h0328 ; elsebegin sr8_2[ 0] <= sr8_2[10] ^ sr8_2[ 8] ^ sr8_2[ 6] ^ sr8_2[ 0]; sr8_2[ 1] <= sr8_2[11] ^ sr8_2[ 9] ^ sr8_2[ 7] ^ sr8_2[ 1]; sr8_2[ 2] <= sr8_2[12] ^ sr8_2[10] ^ sr8_2[ 8] ^ sr8_2[ 2]; sr8_2[ 3] <= sr8_2[13] ^ sr8_2[11] ^ sr8_2[10] ^ sr8_2[ 9] ^ sr8_2[ 8] ^ sr8_2[ 6] ^ sr8_2[ 3]; sr8_2[ 4] <= sr8_2[14] ^ sr8_2[12] ^ sr8_2[11] ^ sr8_2[ 9] ^ sr8_2[ 8] ^ sr8_2[ 7] ^ sr8_2[ 6] ^ sr8_2[ 4]; sr8_2[ 5] <= sr8_2[15] ^ sr8_2[13] ^ sr8_2[12] ^ sr8_2[ 9] ^ sr8_2[ 7] ^ sr8_2[ 6] ^ sr8_2[ 5]; sr8_2[ 6] <= sr8_2[14] ^ sr8_2[13] ^ sr8_2[10] ^ sr8_2[ 8] ^ sr8_2[ 7] ^ sr8_2[ 6] ^ sr8_2[ 0]; sr8_2[ 7] <= sr8_2[15] ^ sr8_2[14] ^ sr8_2[11] ^ sr8_2[ 9] ^ sr8_2[ 8] ^ sr8_2[ 7] ^ sr8_2[ 1]; sr8_2[ 8] <= sr8_2[15] ^ sr8_2[12] ^ sr8_2[10] ^ sr8_2[ 9] ^ sr8_2[ 8] ^ sr8_2[ 2] ^ sr8_2[ 0]; sr8_2[ 9] <= sr8_2[13] ^ sr8_2[11] ^ sr8_2[10] ^ sr8_2[ 9] ^ sr8_2[ 3] ^ sr8_2[ 1]; sr8_2[10] <= sr8_2[14] ^ sr8_2[12] ^ sr8_2[11] ^ sr8_2[10] ^ sr8_2[ 4] ^ sr8_2[ 2] ^ sr8_2[ 0]; sr8_2[11] <= sr8_2[15] ^ sr8_2[13] ^ sr8_2[12] ^ sr8_2[11] ^ sr8_2[ 5] ^ sr8_2[ 3] ^ sr8_2[ 1]; sr8_2[12] <= sr8_2[14] ^ sr8_2[13] ^ sr8_2[12] ^ sr8_2[ 6] ^ sr8_2[ 4] ^ sr8_2[ 2]; sr8_2[13] <= sr8_2[15] ^ sr8_2[14] ^ sr8_2[13] ^ sr8_2[ 7] ^ sr8_2[ 5] ^ sr8_2[ 3]; sr8_2[14] <= sr8_2[15] ^ sr8_2[14] ^ sr8_2[ 8] ^ sr8_2[ 6] ^ sr8_2[ 4]; sr8_2[15] <= sr8_2[15] ^ sr8_2[ 9] ^ sr8_2[ 7] ^ sr8_2[ 5]; end
end always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) sr8_3 <= 16'h284b ; //16'h114b ;16'h284b ; else if(I_sr_rst)sr8_3 <= 16'h284b ; //16'h114b ;16'h284b ; elsebegin sr8_3[ 0] <= sr8_3[10] ^ sr8_3[ 8] ^ sr8_3[ 6] ^ sr8_3[ 0]; sr8_3[ 1] <= sr8_3[11] ^ sr8_3[ 9] ^ sr8_3[ 7] ^ sr8_3[ 1]; sr8_3[ 2] <= sr8_3[12] ^ sr8_3[10] ^ sr8_3[ 8] ^ sr8_3[ 2]; sr8_3[ 3] <= sr8_3[13] ^ sr8_3[11] ^ sr8_3[10] ^ sr8_3[ 9] ^ sr8_3[ 8] ^ sr8_3[ 6] ^ sr8_3[ 3]; sr8_3[ 4] <= sr8_3[14] ^ sr8_3[12] ^ sr8_3[11] ^ sr8_3[ 9] ^ sr8_3[ 8] ^ sr8_3[ 7] ^ sr8_3[ 6] ^ sr8_3[ 4]; sr8_3[ 5] <= sr8_3[15] ^ sr8_3[13] ^ sr8_3[12] ^ sr8_3[ 9] ^ sr8_3[ 7] ^ sr8_3[ 6] ^ sr8_3[ 5]; sr8_3[ 6] <= sr8_3[14] ^ sr8_3[13] ^ sr8_3[10] ^ sr8_3[ 8] ^ sr8_3[ 7] ^ sr8_3[ 6] ^ sr8_3[ 0]; sr8_3[ 7] <= sr8_3[15] ^ sr8_3[14] ^ sr8_3[11] ^ sr8_3[ 9] ^ sr8_3[ 8] ^ sr8_3[ 7] ^ sr8_3[ 1]; sr8_3[ 8] <= sr8_3[15] ^ sr8_3[12] ^ sr8_3[10] ^ sr8_3[ 9] ^ sr8_3[ 8] ^ sr8_3[ 2] ^ sr8_3[ 0]; sr8_3[ 9] <= sr8_3[13] ^ sr8_3[11] ^ sr8_3[10] ^ sr8_3[ 9] ^ sr8_3[ 3] ^ sr8_3[ 1]; sr8_3[10] <= sr8_3[14] ^ sr8_3[12] ^ sr8_3[11] ^ sr8_3[10] ^ sr8_3[ 4] ^ sr8_3[ 2] ^ sr8_3[ 0]; sr8_3[11] <= sr8_3[15] ^ sr8_3[13] ^ sr8_3[12] ^ sr8_3[11] ^ sr8_3[ 5] ^ sr8_3[ 3] ^ sr8_3[ 1]; sr8_3[12] <= sr8_3[14] ^ sr8_3[13] ^ sr8_3[12] ^ sr8_3[ 6] ^ sr8_3[ 4] ^ sr8_3[ 2]; sr8_3[13] <= sr8_3[15] ^ sr8_3[14] ^ sr8_3[13] ^ sr8_3[ 7] ^ sr8_3[ 5] ^ sr8_3[ 3]; sr8_3[14] <= sr8_3[15] ^ sr8_3[14] ^ sr8_3[ 8] ^ sr8_3[ 6] ^ sr8_3[ 4]; sr8_3[15] <= sr8_3[15] ^ sr8_3[ 9] ^ sr8_3[ 7] ^ sr8_3[ 5]; end
end //=====================
always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) scrm_byte0 <= 8'd0 ; else if(I_kcode[0] == 1'b0)begin scrm_byte0[ 0] <= I_data[ 0] ^ sr8_0[15];scrm_byte0[ 1] <= I_data[ 1] ^ sr8_0[14];scrm_byte0[ 2] <= I_data[ 2] ^ sr8_0[13];scrm_byte0[ 3] <= I_data[ 3] ^ sr8_0[12]; scrm_byte0[ 4] <= I_data[ 4] ^ sr8_0[11];scrm_byte0[ 5] <= I_data[ 5] ^ sr8_0[10]; scrm_byte0[ 6] <= I_data[ 6] ^ sr8_0[ 9]; scrm_byte0[ 7] <= I_data[ 7] ^ sr8_0[ 8]; end elsescrm_byte0 <= I_data[7:0];
end always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) scrm_byte1 <= 8'd0 ; else if(I_kcode[1] == 1'b0)begin scrm_byte1[ 0] <= I_data[ 8] ^ sr8_1[15];scrm_byte1[ 1] <= I_data[ 9] ^ sr8_1[14];scrm_byte1[ 2] <= I_data[10] ^ sr8_1[13];scrm_byte1[ 3] <= I_data[11] ^ sr8_1[12]; scrm_byte1[ 4] <= I_data[12] ^ sr8_1[11];scrm_byte1[ 5] <= I_data[13] ^ sr8_1[10]; scrm_byte1[ 6] <= I_data[14] ^ sr8_1[ 9]; scrm_byte1[ 7] <= I_data[15] ^ sr8_1[ 8]; end elsescrm_byte1 <= I_data[15:8];
end always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) scrm_byte2 <= 8'd0 ; else if(I_kcode[2] == 1'b0)begin scrm_byte2[ 0] <= I_data[16] ^ sr8_2[15];scrm_byte2[ 1] <= I_data[17] ^ sr8_2[14];scrm_byte2[ 2] <= I_data[18] ^ sr8_2[13];scrm_byte2[ 3] <= I_data[19] ^ sr8_2[12]; scrm_byte2[ 4] <= I_data[20] ^ sr8_2[11];scrm_byte2[ 5] <= I_data[21] ^ sr8_2[10]; scrm_byte2[ 6] <= I_data[22] ^ sr8_2[ 9]; scrm_byte2[ 7] <= I_data[23] ^ sr8_2[ 8]; end elsescrm_byte2 <= I_data[23:16];
end always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) scrm_byte3 <= 8'd0 ; else if(I_kcode[3] == 1'b0)begin scrm_byte3[ 0] <= I_data[24] ^ sr8_3[15];scrm_byte3[ 1] <= I_data[25] ^ sr8_3[14];scrm_byte3[ 2] <= I_data[26] ^ sr8_3[13];scrm_byte3[ 3] <= I_data[27] ^ sr8_3[12]; scrm_byte3[ 4] <= I_data[28] ^ sr8_3[11];scrm_byte3[ 5] <= I_data[29] ^ sr8_3[10]; scrm_byte3[ 6] <= I_data[30] ^ sr8_3[ 9]; scrm_byte3[ 7] <= I_data[31] ^ sr8_3[ 8]; end elsescrm_byte3 <= I_data[31:24];
end //----------------------
always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) beginscrm_kcode_d1 <= 4'd0;scrm_kcode_d2 <= 4'd0;scrm_data_d1 <= 32'd0;scrm_data_d2 <= 32'd0;endelsebeginscrm_kcode_d1 <= I_kcode_d1;scrm_kcode_d2 <= scrm_kcode_d1;scrm_data_d1 <= {scrm_byte3,scrm_byte2,scrm_byte1,scrm_byte0};scrm_data_d2 <= scrm_data_d1;end
endassign O_kcode = (SEQUENCY == 2'd0) ? scrm_kcode_d2 :(SEQUENCY == 2'd1) ? {scrm_kcode_d1[0],scrm_kcode_d2[3:1]} : (SEQUENCY == 2'd2) ? {scrm_kcode_d1[1:0],scrm_kcode_d2[3:2]} : (SEQUENCY == 2'd3) ? {scrm_kcode_d1[2:0],scrm_kcode_d2[3]} : scrm_kcode_d2;
assign O_data = (SEQUENCY == 2'd0) ? scrm_data_d2 :(SEQUENCY == 2'd1) ? {scrm_data_d1[7:0],scrm_data_d2[31:8]} : (SEQUENCY == 2'd2) ? {scrm_data_d1[15:0],scrm_data_d2[31:16]} : (SEQUENCY == 2'd3) ? {scrm_data_d1[23:0],scrm_data_d2[31:24]} : scrm_data_d2;endmodule
解扰descramble模块中的LFSR直接根据DP协议附录中参考代码进行迭代,一共四组数据,第一组就是移位8个时钟周期的LFSR输出,依次类推,第二组就是移位16个时钟周期的LFSR输出,第三组就是移位24个时钟周期的LFSR输出,第四组就是移位32个时钟周期的LFSR输出。注意,采用这种方式实现,每组LFSR的复位初始值都相同。
因为加扰和解扰使用的是相同的电路结构,所以此解扰descramble模块也可以做加扰scramble模块使用。此代码可以在实际应用中使用。
module descramble
( input I_rst_n ,//low activeinput I_clk ,input [32/8-1:0] I_kcode ,input [32-1:0] I_data ,//low byte firstoutput [32/8-1:0] O_kcode , output [32-1:0] O_data //descramble
);localparam SR_SYM = 8'h1C; //K28.0localparam N = 4;// Symbols per lane//=====================
wire[15:0] sri[0:3];//四组LFSR 级联
reg [15:0] sro[0:3];
reg [15:0] sro_hi; wire[3:0] k_in;
wire[7:0] d_in[0:3]; //数据按字节分组wire[3:0] sr_symbl;
wire[3:0] sr_reset; reg [3:0] k_out;
reg [7:0] d_out[0:3];genvar i;
integer j;//====================
assign k_in[0] = I_kcode[0];
assign k_in[1] = I_kcode[1];
assign k_in[2] = I_kcode[2];
assign k_in[3] = I_kcode[3];
assign d_in[0] = I_data[ 7: 0];
assign d_in[1] = I_data[15: 8];
assign d_in[2] = I_data[23:16];
assign d_in[3] = I_data[31:24];//=====================
//SR symbol detect
assign sr_reset[0] = (k_in[0] & (d_in[0] == SR_SYM)) ? 1'b1 : 1'b0;
assign sr_reset[1] = (k_in[1] & (d_in[1] == SR_SYM)) ? 1'b1 : 1'b0;
assign sr_reset[2] = (k_in[2] & (d_in[2] == SR_SYM)) ? 1'b1 : 1'b0;
assign sr_reset[3] = (k_in[3] & (d_in[3] == SR_SYM)) ? 1'b1 : 1'b0;//=====================
//LFSR 并行结构,参考DP协议手册
assign sri[0] = sro_hi;
assign sri[1] = sro[0];
assign sri[2] = sro[1];
assign sri[3] = sro[2];// LFSR
always@(*)
begin if(sr_reset[0])sro[0] <= 16'hffff ; //16'hfffe ;16'hffff ;elsebegin sro[0][ 0] <= sri[0][ 8]; sro[0][ 1] <= sri[0][ 9]; sro[0][ 2] <= sri[0][10]; sro[0][ 3] <= sri[0][11] ^ sri[0][ 8]; sro[0][ 4] <= sri[0][12] ^ sri[0][ 9] ^ sri[0][ 8]; sro[0][ 5] <= sri[0][13] ^ sri[0][10] ^ sri[0][ 9] ^ sri[0][ 8]; sro[0][ 6] <= sri[0][14] ^ sri[0][11] ^ sri[0][10] ^ sri[0][ 9]; sro[0][ 7] <= sri[0][15] ^ sri[0][12] ^ sri[0][11] ^ sri[0][10]; sro[0][ 8] <= sri[0][ 0] ^ sri[0][13] ^ sri[0][12] ^ sri[0][11]; sro[0][ 9] <= sri[0][ 1] ^ sri[0][14] ^ sri[0][13] ^ sri[0][12]; sro[0][10] <= sri[0][ 2] ^ sri[0][15] ^ sri[0][14] ^ sri[0][13]; sro[0][11] <= sri[0][ 3] ^ sri[0][15] ^ sri[0][14]; sro[0][12] <= sri[0][ 4] ^ sri[0][15]; sro[0][13] <= sri[0][ 5]; sro[0][14] <= sri[0][ 6]; sro[0][15] <= sri[0][ 7]; end
end always@(*)
begin if(sr_reset[1])sro[1] <= 16'hffff ; //16'hfffe ;16'hffff ;elsebegin sro[1][ 0] <= sri[1][ 8]; sro[1][ 1] <= sri[1][ 9]; sro[1][ 2] <= sri[1][10]; sro[1][ 3] <= sri[1][11] ^ sri[1][ 8]; sro[1][ 4] <= sri[1][12] ^ sri[1][ 9] ^ sri[1][ 8]; sro[1][ 5] <= sri[1][13] ^ sri[1][10] ^ sri[1][ 9] ^ sri[1][ 8]; sro[1][ 6] <= sri[1][14] ^ sri[1][11] ^ sri[1][10] ^ sri[1][ 9]; sro[1][ 7] <= sri[1][15] ^ sri[1][12] ^ sri[1][11] ^ sri[1][10]; sro[1][ 8] <= sri[1][ 0] ^ sri[1][13] ^ sri[1][12] ^ sri[1][11]; sro[1][ 9] <= sri[1][ 1] ^ sri[1][14] ^ sri[1][13] ^ sri[1][12]; sro[1][10] <= sri[1][ 2] ^ sri[1][15] ^ sri[1][14] ^ sri[1][13]; sro[1][11] <= sri[1][ 3] ^ sri[1][15] ^ sri[1][14]; sro[1][12] <= sri[1][ 4] ^ sri[1][15]; sro[1][13] <= sri[1][ 5]; sro[1][14] <= sri[1][ 6]; sro[1][15] <= sri[1][ 7]; end
end always@(*)
begin if(sr_reset[2])sro[2] <= 16'hffff ; //16'hfffe ;16'hffff ;elsebegin sro[2][ 0] <= sri[2][ 8]; sro[2][ 1] <= sri[2][ 9]; sro[2][ 2] <= sri[2][10]; sro[2][ 3] <= sri[2][11] ^ sri[2][ 8]; sro[2][ 4] <= sri[2][12] ^ sri[2][ 9] ^ sri[2][ 8]; sro[2][ 5] <= sri[2][13] ^ sri[2][10] ^ sri[2][ 9] ^ sri[2][ 8]; sro[2][ 6] <= sri[2][14] ^ sri[2][11] ^ sri[2][10] ^ sri[2][ 9]; sro[2][ 7] <= sri[2][15] ^ sri[2][12] ^ sri[2][11] ^ sri[2][10]; sro[2][ 8] <= sri[2][ 0] ^ sri[2][13] ^ sri[2][12] ^ sri[2][11]; sro[2][ 9] <= sri[2][ 1] ^ sri[2][14] ^ sri[2][13] ^ sri[2][12]; sro[2][10] <= sri[2][ 2] ^ sri[2][15] ^ sri[2][14] ^ sri[2][13]; sro[2][11] <= sri[2][ 3] ^ sri[2][15] ^ sri[2][14]; sro[2][12] <= sri[2][ 4] ^ sri[2][15]; sro[2][13] <= sri[2][ 5]; sro[2][14] <= sri[2][ 6]; sro[2][15] <= sri[2][ 7]; end
end always@(*)
begin if(sr_reset[3])sro[3] <= 16'hffff ; //16'hfffe ;16'hffff ;elsebegin sro[3][ 0] <= sri[3][ 8]; sro[3][ 1] <= sri[3][ 9]; sro[3][ 2] <= sri[3][10]; sro[3][ 3] <= sri[3][11] ^ sri[3][ 8]; sro[3][ 4] <= sri[3][12] ^ sri[3][ 9] ^ sri[3][ 8]; sro[3][ 5] <= sri[3][13] ^ sri[3][10] ^ sri[3][ 9] ^ sri[3][ 8]; sro[3][ 6] <= sri[3][14] ^ sri[3][11] ^ sri[3][10] ^ sri[3][ 9]; sro[3][ 7] <= sri[3][15] ^ sri[3][12] ^ sri[3][11] ^ sri[3][10]; sro[3][ 8] <= sri[3][ 0] ^ sri[3][13] ^ sri[3][12] ^ sri[3][11]; sro[3][ 9] <= sri[3][ 1] ^ sri[3][14] ^ sri[3][13] ^ sri[3][12]; sro[3][10] <= sri[3][ 2] ^ sri[3][15] ^ sri[3][14] ^ sri[3][13]; sro[3][11] <= sri[3][ 3] ^ sri[3][15] ^ sri[3][14]; sro[3][12] <= sri[3][ 4] ^ sri[3][15]; sro[3][13] <= sri[3][ 5]; sro[3][14] <= sri[3][ 6]; sro[3][15] <= sri[3][ 7]; end
end always@(posedge I_clk or negedge I_rst_n)
begin if(!I_rst_n) sro_hi <= 16'd0;elsesro_hi = sro[3];
end//=====================
generatefor (i = 0; i < N; i=i+1)begin : gen_scrm_doutalways@(posedge I_clk or negedge I_rst_n) begin if(!I_rst_n) d_out[i] <= 8'd0;else if(k_in[i] == 1'b0)for (j = 0; j < 8; j=j+1)begin d_out[i][j] <= d_in[i][j] ^ sri[i][15-j];end elsed_out[i] <= d_in[i];end always@(posedge I_clk or negedge I_rst_n) begin if(!I_rst_n) k_out[i] <= 1'b0;elsek_out[i] <= k_in[i];endend
endgenerate assign O_kcode[0] = k_out[0];
assign O_kcode[1] = k_out[1];
assign O_kcode[2] = k_out[2];
assign O_kcode[3] = k_out[3];
assign O_data[ 7: 0] = d_out[0];
assign O_data[15: 8] = d_out[1];
assign O_data[23:16] = d_out[2];
assign O_data[31:24] = d_out[3];endmodule
仿真工程如下地址下载https://download.csdn.net/download/cjie221/90633901
仿真波形如下,经过加扰后再解扰,最终数据与原始数据一致。