高速接口中的PRBS的设计

http://bbs.ednchina.com/BLOG_ARTICLE_3018596.HTM

在高速设计中,为了测试高速串行通道传输的误码率,通常通过发送PRBS码来进行测试

原理:用生产函数产生一段随机码流,然后按周期循环。

PRBS码的周期长度与其阶数有关,常用的阶数有7,9,11,15,20,23,31.

对于N阶PRBS码,每个周期的序列长度为2^N-1.

在每个周期内,0和1时随机分布的,并且0和1的个数相等。

连续个1的最大数目为n,连续个0的最大数目为n-1(反转后就是n-1个连续1和n个连续0)。

在对高速信号链路进行误码测试时,基本上都是利用PRBS码流来模拟真实的线网码流环境,因为在线网中,所有的数据都是随机出现的,没有任何规律可言,而PRBS码流在一定程度上具有这种“随机数据”特性,二进制0和1随机出现,其频谱特征与白噪声非常接近。PRBS码流的阶数越高,其包含的码流就越丰富,就越接近真实的线网环境,测试的结果就越准确。

一个PRBS序列可以串/并转换成多路(2、4、8、16.路),每路输出的速率降低,但仍然保持原序列的所有特诊,反之,同一时钟源低速多路(2、4、8、16..路)同一个n数的PRBS可以经并/串转换成高速率的n阶PRBS。

下面采用verilog来设计PRBS模块,可以通过外部参数配置PRBS7, PRBS9, PRBS15, PRBS23, PRBS31,

 

`timescale 1ns / 1ps

 

module prbs_gen

#(

parameter PRBS_WIDTH = 32,

parameter PRBS_PATTERN = "prbs7"  //prbs7,prbs9.prbs15,prbs23,prbs31

)

(

    input                    sys_clk,    //系统时钟

    input                    reset_n,    //系统复位

    input                    prbs_en,   //enable_prbs

    input                    inser_err,

    output [PRBS_WIDTH-1:0] prbs_data  //prbs_out

);

    reg [PRBS_WIDTH-1:0] prbs_reg;

    reg [PRBS_WIDTH-1:0] tx_data;

    wire feed_data;

    wire [PRBS_WIDTH-1:0] prbs_d;

integer m;

//本原多项式

//prbs7 = 1+x^6+x^7

//prbs9 = 1+x^5+x^9

//prbs15 = 1+x^14+x^15

//prbs23 = 1+x^18+x^23

//prbs31 = 1+x^28+x^31

 

localparam PRI_MAX_WIDTH = 40;

wire [PRI_MAX_WIDTH-1:0] prbs_pri_val;

 

reg prbs_en_d0,prbs_en_d1;

 

assign prbs_pri_val = (PRBS_PATTERN == "prbs7")? 40'b0011000001:

                   (PRBS_PATTERN == "prbs9")? 40'b1000100001:

                   (PRBS_PATTERN == "prbs15")? 40'b0000110000__0000000001:

                   (PRBS_PATTERN == "prbs23")? 40'b0000001000_0100000000_1000100001:

                   (PRBS_PATTERN == "prbs31")? 40'b0000000010_0100000000_0000000000_0000000001:0011000001;

 

localparam reset_seed = 40'haa_aaaa_aaaa;

 

always @(posedge sys_clk or negedge reset_n) begin

  if(~reset_n) begin

      prbs_en_d0 <= #1 'b0;

      prbs_en_d1 <= #1 'b0;

  end

  else begin

      prbs_en_d0 <= #1 prbs_en;

      prbs_en_d1 <= #1 prbs_en_d0;

  end

end

 

always @(posedge sys_clk or negedge reset_n) begin

  if(reset_n == 1'b0)  begin

    prbs_reg <= prbs_pri_val[(PRBS_WIDTH-1):0];

    //prbs_reg <= prbs_pri_val[7:0];

  end

  else if(prbs_en_d1) begin

    for(m =1; m< PRBS_WIDTH; m = m+1)

        prbs_reg[PRBS_WIDTH-m-1] <=  prbs_reg[PRBS_WIDTH-m];

    prbs_reg[PRBS_WIDTH-1]   <=  feed_data;

  end

  else

     prbs_reg[PRBS_WIDTH-1:0]   <=  prbs_reg[PRBS_WIDTH-1:0];

end

 

assign prbs_d  = prbs_reg & prbs_pri_val[(PRBS_WIDTH-1):0];

assign feed_data = ^prbs_d;

 

reg inser_err_d0;

reg inser_err_d1;

reg detect_insererr;

 

always @(posedge sys_clk or negedge reset_n) begin

  if(reset_n == 1'b0) begin

      tx_data         <= reset_seed[PRBS_WIDTH-1:0];

      inser_err_d0    <= 1'b0;

      inser_err_d1    <= 1'b0;

      detect_insererr <= 1'b0;

  end

  else begin

     inser_err_d0 <= inser_err;

     inser_err_d1 <= inser_err_d0;

     if(inser_err_d0 == 1'b1 && inser_err_d1 == 1'b0)

         detect_insererr <= 1'b1;

     else

         detect_insererr <= 1'b0;

 

     if(detect_insererr == 1'b1)

         tx_data <= {~prbs_reg[PRBS_WIDTH-1],prbs_reg[PRBS_WIDTH-2:0]};

     else

         tx_data <= prbs_reg[PRBS_WIDTH-1:0];

  end

end

assign prbs_data = tx_data;

 

endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值