为什么要并行
简单来说,串行PRBS的产生在高速时极不可靠。
因为构成寄存器的触发器运行速度在串行时必须与传输速度一致,其运算速度的提高完全依靠于时钟的速度。当信号速率高达上GHz时,每比特的宽度要小于1 ns。而已商品化的高速GaAs器件在2GHz的触发时钟到输出的延时仍有0.7ns,普通的高速器件延时更大。电路中连接器件的印制线路也会产生传输延时,若传输延时超过时钟周期,触发器就会产生误触发。
采用并行方式,以字节的方式产生伪随机码,即每个时钟脉冲输出并行8位数据信号,形成8路低速伪随机序列。可以将工作时钟频率降低到串行产生伪随机码的时钟频率的1/8,也就是说要产生1GHz时钟频率的伪随机序列,只需125MHz的时钟驱动即可。
并行实现思路
以生成16位的prbs15信号为例,本原多项式是X15+X14+1
PRBS发生器通常是由线性反馈移位寄存器(linear feedback shift registers,LFSR)和异或电路组成。
串行实现思路:将寄存器的第14位和第13位做异或运算后,输入到寄存器的第0位,寄存器的第14位同时也是PRBS15发生器的输出。
并行实现思路:给定初始的15位shift,做异或后的结果存入fb,输出的16位如图所示;下一个clk,fb的低15位构成新的shift,再做异或运算。
代码 module prbs15 //16位并行的prbs15 inputwireclk,inputwirerst,inputwire[14:0]prbs_ini,outputwire[15:0]prbs_out);reg [14:0] shift; //移位寄存器wire [15:0] data_fb; //xor feedback//移位寄存always@posedge clk) beginifrst)shift <= prbs_ini;else beginshift <= data_fb[14:0]; endend//异或assign data_fb[15:2] = shift[14:1]^shift[13:0];assign data_fb[1] = shift[0]^data_fb[15];assign data_fb[0] = data_fb[15]^data_fb[14];//移位寄存器中的结果是输出assign prbs_out = {shift[14:0],data_fb[15]};endmodule 仿真
testbench
module test_vlg_tst);reg clk;reg [14:0] prbs_ini;reg rst; wire [15:0] prbs_out; test i1 .clkclk),.prbs_iniprbs_ini),.prbs_outprbs_out),.rstrst)); initial beginclk = 0;rst = 1;prbs_ini = 15’d2;#20 rst = 0;#10000 $stop;end//注意rst复位至少要留够一个clk,否则会没有复位,信号仿真结果xxxxalways #10 clk = ~clk;endmodule
与串行prbs15的结果一致
串行PRBS15outxorprbs更新00000_0000_0000_01000000 0000 0000 0100 0000 0000 0000 0100 00000000 0000 0100 00000000 0000 0100 00000000 0000 0100 0000 0000 0000 0100 0000 00000000 0100 0000 00000000 0100 0000 00000000 0100 0000 0000 0000 0100 0000 0000 00000100 0000 0000 00001100 0000 0000 00011100 0000 0000 0001 1000 0000 0000 0001 10000000 0000 0001 10000000 0000 0001 10000000 0000 0001 1000 0000 0000 0001 1000 00000000 0001 1000 00000000 0001 1000 00000000 0001 1000 0000 0000 0001 1000 0000 00000001 1000 0000 00000001 1000 0000 00000001 1000 0000 0000 0011 1000 0000 0000 01101000 0000 0000 01011000 0000 0000 01010000 0000 0000 0101 0000 0000 0000 0101 00000000 0000 0101 000 新写法
这样写思路更清晰
module prbs15_gen //64bitinput clk,input rst,output [63:0] prbs_out);parameter DATA_INI = 15’d2;reg [14:0] shift1;wire [14:0] shift2,shift3,shift4;wire [3:0] shift5;always@posedge clk or posedge rst) beginifrst)shift1 <= DATA_INI;else beginshift1 <= prbs_out1[14:0]; endendassign shift2[14:1] = shift1[14:1] ^ shift1[13:0];assign shift2[0] = shift1[0] ^ shift2[14];assign shift3[14:1] = shift2[14:1] ^ shift2[13:0];assign shift3[0] = shift2[0] ^ shift3[14];assign shift4[14:1] = shift3[14:1] ^ shift3[13:0];assign shift4[0] = shift3[0] ^ shift4[14];assign shift5[3:0] = shift4[14:11] ^ shift4[13:0];assign prbs_out = {shift1,shift2,shift3,shift4,shift5};endmodule