伪随机码PRBS与线性反馈移位寄存器LFSR

伪随机码PRBS与线性反馈移位寄存器LFSR 伪随机码PRBSPRBS是Pseudo-Random Binary Sequence伪随机二进制序列的缩写它是一种在数字通信、测试测量和系统控制等领域应用非常广泛的信号。它是一种可以预先确定、可重复生成但又具备随机统计特性的二进制序列。PRBS按照不同阶数可分为PRBS7PRBS15PRBS23PRBS31伪随机序列中“0”和“1”的出现概率大致相等能够很好地模拟真实通信信号中的随机数据因此也通常采用伪随机序列对通信系统进行测试在高速串行总线如PCIe, USB, Ethernet的物理层测试中通常用PRBS码型作为激励信号在接收端测量眼图、抖动和误码率以此来评估链路的信号完整性。一个能通过PRBS31考验的链路其传输质量无疑是过硬的。PRBS的生成原理PRBS是由“线性反馈移位寄存器Linear Feedback Shift Register简称LFSR”生成。线性反馈移位寄存器就像一个由多个寄存器排成一排组成的队列在每一个时钟周期队列里的数据都会向右移动一格而最左边空出来的位置则会根据队列中某些特定位置抽头的值进行异或XOR运算后填入。这个循环往复的过程就能生成一串看似随机、实则有规律的序列。这些抽头由反馈多项式决定例如x³ x² 1它决定了从寄存器的哪些位置我们称之为“抽头”取出数据进行异或运算。用线性反馈移位寄存器生成伪随机码的Verilog代码如下//采用PRBS15,多项式为X15 X14 X13 1 module PRBS( input clk , input rst , output [31:0] o_prbs ); parameter PRBS_INIT 16ha076; reg [31:0] ro_prbs ; wire [47:0] w_prbs ; reg [15:0] r_prbs ; assign o_prbs ro_prbs; assign w_prbs[47:32] r_prbs; always (posedge clk or posedge rst) begin if(rst) r_prbs PRBS_INIT; else r_prbs w_prbs[15:0]; end genvar i; generate for (i 0;i 32;i i1 ) begin:prbs_loop assign w_prbs[31-i] w_prbs[47-i] ^ w_prbs[46-i] ^ w_prbs[45-i] ^ w_prbs[32-i]; //依次将高位舍弃将亦或后的结果拼接到低位 end endgenerate always (posedge clk or posedge rst) begin if(rst) ro_prbs 32h0; else ro_prbs w_prbs[31:0]; end endmodule仿真如下module PRBS_sim(); reg clk ; reg rst ; always #10 clk ~clk; initial begin clk 0; rst 1; #100; rst 0; #1000; $finish(); end PRBS PRBS_u0( .clk (clk ), .rst (rst ), .o_prbs ( ) ); endmodule还可以用线性反馈移位寄存器对数据进行加扰和解扰下面的代码是GT收发器IP核官方例程中对输入数据的加扰和解扰。加扰代码timescale 1ns / 1ps define DLY #1 //***********************************Entity Declaration******************************* module SCRAMBLER # ( parameter TX_DATA_WIDTH 32 ) ( // User Interface input wire [(TX_DATA_WIDTH-1):0] UNSCRAMBLED_DATA_IN , input wire DATA_VALID_IN , output reg [(TX_DATA_WIDTH-1):0] SCRAMBLED_DATA_OUT , // System Interface input wire USER_CLK , input wire SYSTEM_RESET ); //***************************Internal Register Declarations******************** integer i ; reg [57:0] poly ; reg [(TX_DATA_WIDTH-1):0] scrambled_data_i ; reg [57:0] scrambler ; reg [(TX_DATA_WIDTH-1):0] tempData ; reg xorBit ; //*********************************Main Body of Code*************************** always (scrambler,UNSCRAMBLED_DATA_IN) begin poly scrambler; for (i0;i(TX_DATA_WIDTH-1);ii1) begin xorBit UNSCRAMBLED_DATA_IN[i] ^ poly[38] ^ poly[57]; poly {poly[56:0],xorBit}; tempData[i] xorBit; end end //________________ Scrambled Data assignment to output port _______________ always (posedge USER_CLK) begin if (SYSTEM_RESET) begin SCRAMBLED_DATA_OUT DLY h0; scrambler DLY 58h155_5555_5555_5555; end else if (DATA_VALID_IN) begin SCRAMBLED_DATA_OUT DLY tempData; scrambler DLY poly; end end endmodule解扰代码timescale 1ns / 1ps define DLY #1 //***********************************Entity Declaration******************************* module DESCRAMBLER # ( parameter RX_DATA_WIDTH 32 ) ( // User Interface input wire [(RX_DATA_WIDTH-1):0] SCRAMBLED_DATA_IN , input wire DATA_VALID_IN , output reg [(RX_DATA_WIDTH-1):0] UNSCRAMBLED_DATA_OUT , // System Interface input wire USER_CLK , input wire SYSTEM_RESET ); //***************************Internal Register Declarations******************** reg [57:0] descrambler ; integer i ; reg [57:0] poly ; reg [(RX_DATA_WIDTH-1):0] tempData ; reg [(RX_DATA_WIDTH-1):0] unscrambled_data_i ; reg xorBit ; //*********************************Main Body of Code*************************** always (descrambler,SCRAMBLED_DATA_IN) begin poly descrambler; for (i0;i(RX_DATA_WIDTH-1);ii1) begin xorBit SCRAMBLED_DATA_IN[i] ^ poly[38] ^ poly[57]; poly {poly[56:0],SCRAMBLED_DATA_IN[i]}; tempData[i] xorBit; end end //________________ Scrambled Data assignment to output port _______________ always (posedge USER_CLK) begin if (SYSTEM_RESET) begin UNSCRAMBLED_DATA_OUT DLY h0; descrambler DLY 58h155_5555_5555_5555; end else if (DATA_VALID_IN) begin UNSCRAMBLED_DATA_OUT DLY tempData; descrambler DLY poly; end end endmodule