Aurora测试----随机数字产生

      在xilinx模板中,存在一个Aurora样本工程,包含众多的子函数,本系列本文将逐一对其进行解析,首先是aurora_8b10b_0_FRAME_GEN函数,根据官方的说明,其作用是:该模块是一个模式生成器,用于在硬件上测试激光设计。它生成数据并将其通过激光通道。如果连接到帧接口,它将生成不同大小和间隔的帧。LFSR用于产生伪随机数据,LFSR的低位连接到REM总线。

       REM在此处的含义应该是remaining,其输出接到下一个模块的LL_IP_REM接口,根据其数值令TKKP为10 or 11,是的产后是呢过的数据更加随机。

1、复位管理模块

   

//*********************************Main Body of Code**********************************

  always @ (posedge USER_CLK)
  begin
    if(RESET)
        channel_up_cnt <= `DLY 5'd0;
    else if(CHANNEL_UP)
      if(&channel_up_cnt)
        channel_up_cnt <= `DLY channel_up_cnt;
      else 
        channel_up_cnt <= `DLY channel_up_cnt + 1'b1;
    else
      channel_up_cnt <= `DLY 5'd0;
  end

  assign dly_data_xfer = (&channel_up_cnt);

  //Generate RESET signal when Aurora channel is not ready
  assign reset_c = RESET || !dly_data_xfer;

       RESET为模块复位输入信号,除此之外,aurora ip还会产生一个channel_up信号输出,该信号额官方含义为:Asserted when Aurora 8B/10B channel initialization is complete and the channel is ready for data transfer. tx_channel_up and rx_channel_up are only applicable to their respective simplex cores.,也就是当Aurora 8B/10B通道初始化完成且通道准备好进行数据传输时置一CHANNEL_UP。

       当channel_up延时等待16个时钟,&channel_up_cnt表示各个位相与,即各个位为1,故此处就是让帧数据生成单元延时复位操作。

2、生成随机数据模块

    就是一个LFSR(linear feedback shift register,线性反馈移位寄存器),生成有顾虑的随机数

    //______________________________ Transmit Data  __________________________________   
    //Generate random data using XNOR feedback LFSR
    always @(posedge USER_CLK)
        if(reset_c)
        begin
            data_lfsr_r          <=  `DLY    16'hABCD;  //random seed value
        end
        else if(!TX_DST_RDY_N && !idle_r)
        begin
            data_lfsr_r          <=  `DLY    {!{data_lfsr_r[3]^data_lfsr_r[12]^data_lfsr_r[14]^data_lfsr_r[15]},
                                data_lfsr_r[0:14]};
        end

其仿真(modelsim)结果为

3、帧数据计数器与发送数据个数计数器

   官方架构中使用了两个always块,一个always块产生每一帧数据发送的最大数据个数,然后另一个always块计数已发送的数据个数,当两个计数器的数值相等时代表一帧数据发送完毕。

   代码:

   //Use a counter to determine the size of the next frame to send
    always @(posedge USER_CLK)
        if(reset_c)  
            frame_size_r    <=  `DLY    8'h00;
        else if(single_cycle_frame_r || eof_r)
            frame_size_r    <=  `DLY    frame_size_r + 1;
           
    //Use a second counter to determine how many bytes of the frame have already been sent
    always @(posedge USER_CLK)
        if(reset_c)
            bytes_sent_r    <=  `DLY    8'h00;
        else if(sof_r)
            bytes_sent_r    <=  `DLY    8'h01;
        else if(!TX_DST_RDY_N && !idle_r)
            bytes_sent_r    <=  `DLY    bytes_sent_r + 1;

 

此外,在数据的传输过程中,使用计数器产生一个ifg_size_r,使得ifg_size_c每个15个时钟产生一个时钟的高电平,这个信号控制个控制值信号的刷新频率。(个人理解)

    //Use a freerunning counter to determine the IFG
    always @(posedge USER_CLK)
        if(reset_c)
            ifg_size_r      <=  `DLY    4'h0;
        else
            ifg_size_r      <=  `DLY    ifg_size_r + 1;
           
    //IFG is done when ifg_size register is 0
    assign  ifg_done_c  =   (ifg_size_r == 4'h0);   

4、独热码状态机

    本always块控制着状态的转移,状态输出信号控制这信号的发送(主要是生成了Tlast和Tvalid信号)

 //State registers for 1-hot state machine
    always @(posedge USER_CLK)
        if(reset_c)
        begin
            idle_r                  <=  `DLY    1'b1;
            single_cycle_frame_r    <=  `DLY    1'b0;
            sof_r                   <=  `DLY    1'b0;
            data_cycle_r            <=  `DLY    1'b0;
            eof_r                   <=  `DLY    1'b0;
        end
        else if(!TX_DST_RDY_N)
        begin
            idle_r                  <=  `DLY    next_idle_c;
            single_cycle_frame_r    <=  `DLY    next_single_cycle_frame_c;
            sof_r                   <=  `DLY    next_sof_c;
            data_cycle_r            <=  `DLY    next_data_cycle_c;
            eof_r                   <=  `DLY    next_eof_c;
        end
       

  idle_r=0表示空闲状态,不进行数据传输,idle=0表示一帧数据,single_cycle_frame_r表示一帧新的数据准备好开始传输,sof_r表示开始一帧数据的开始,data_cycyle_r表示正在进行数据传输,eof_r表示数据传输结束。

 //Nextstate logic for 1-hot state machine
    assign  next_idle_c                 =   !ifg_done_c &&
                                            (single_cycle_frame_r || eof_r || idle_r);
   
    assign  next_single_cycle_frame_c   =   (ifg_done_c && (frame_size_r == 0)) &&
                                            (idle_r || single_cycle_frame_r || eof_r);
                                           
    assign  next_sof_c                  =   (ifg_done_c && (frame_size_r != 0)) &&
                                            (idle_r || single_cycle_frame_r || eof_r);
                                           
    assign  next_data_cycle_c           =   (frame_size_r != bytes_sent_r) &&
                                            (sof_r || data_cycle_r);
                                           
    assign  next_eof_c                  =   (frame_size_r == bytes_sent_r) &&
                                            (sof_r || data_cycle_r);

        使用杜热码的形式进行状态机切换,根据所处状态生成last和valid信号

 

 

 

 

 

 

 

posted on 2019-11-19 16:51  &#128023;  阅读(704)  评论(0编辑  收藏  举报

导航