在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信号