在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 'd0;
else if(CHANNEL_UP)
if(&channel_up_cnt)
channel_up_cnt <= `DLY channel_up_cnt;
else
channel_up_cnt <= `DLY channel_up_cnt + 'b1;
else
channel_up_cnt <= `DLY '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 'hABCD; //random seed value
end
else if(!TX\_DST\_RDY\_N && !idle\_r)
begin
data\_lfsr\_r <= \`DLY {!{data\_lfsr\_r\[\]^data\_lfsr\_r\[\]^data\_lfsr\_r\[\]^data\_lfsr\_r\[\]},
data\_lfsr\_r\[:\]};
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 'h00;
else if(single_cycle_frame_r || eof_r)
frame_size_r <= `DLY frame_size_r + ;
//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 'h00;
else if(sof\_r)
bytes\_sent\_r <= \`DLY 'h01;
else if(!TX\_DST\_RDY\_N && !idle\_r)
bytes\_sent\_r <= \`DLY bytes\_sent\_r + ;
此外,在数据的传输过程中,使用计数器产生一个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 'h0;
else
ifg\_size\_r <= \`DLY ifg\_size\_r + ;
//IFG is done when ifg\_size register is 0
assign ifg\_done\_c = (ifg\_size\_r == 'h0);
4、独热码状态机
本always块控制着状态的转移,状态输出信号控制这信号的发送(主要是生成了Tlast和Tvalid信号)
//State registers for 1-hot state machine
always @(posedge USER_CLK)
if(reset_c)
begin
idle_r <= `DLY 'b1;
single_cycle_frame_r <= `DLY 'b0;
sof_r <= `DLY 'b0;
data_cycle_r <= `DLY 'b0;
eof_r <= `DLY '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 == )) &&
(idle\_r || single\_cycle\_frame\_r || eof\_r);
assign next\_sof\_c = (ifg\_done\_c && (frame\_size\_r != )) &&
(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信号
手机扫一扫
移动阅读更方便
你可能感兴趣的文章