目录
前言
一、接收异常保护
二、超短包、背靠背的支持
后记
前言
为了系统的鲁棒性,我们常常会做一系列的异常保护功能,避免系统挂死。
这里仅仅介绍接收保护的某些设计思路,抛砖引玉。
一、接收异常保护
设计思路:通过可配置的门限阈值来对超长包/异常包进行截断处理,并将异常情况上报。
这里门限可分为两种,一是数据包的长度,二是时间。
当接收数据超过门限(超长/超时)而还没收到eop信号的时候,就截断报文,并自行产生一个eop信号。
下面以超时为例,简单写下代码:
input [31:0] i_cut_cycle_threshold;//寄存器配置,可加使能信号
input [31:0] i_cut_len_threshold;
output reg [31:0] o_rpt_cycle_cut_cnt;//异常上报
output reg [31:0] o_rpt_len_cut_cnt;reg s_frm_running;
reg [31:0] s_cycle_cnt;assign s_rx_sop = i_rx_sop && i_rx_vld && o_rx_rdy;
assign s_rx_eop = (i_rx_eop && i_rx_vld && o_rx_rdy) || s_cycle_cut_en;
assign s_cycle_cut_en = s_cycle_cnt >= i_cut_cycle_threshold;always@(posedge clk or negedge rst_n)beginif(~rst_n)s_frm_running <= 1'b0;else if(s_rx_eop)s_frm_running <= 1'b0;else if(s_rx_sop)s_frm_running <= 1'b1;
endalways@(posedge clk or negedge rst_n)beginif(~rst_n)s_cycle_cnt <= 32'b0;else if(s_rx_eop || s_rx_sop)s_cycle_cnt <= 32'b0;else if(s_frm_running) s_cycle_cnt <= s_cycle_cnt + 32'd1;
endalways@(posedge clk or negedge rst_n)beginif(~rst_n) o_rpt_cycle_cut_cnt <= 32'b0;else if(s_cycle_cut_en)o_rpt_cycle_cut_cnt <= o_rpt_cycle_cut_cnt + 32'd1;
end
超长包截断代码大致相同,就不啰嗦了,重点是设计时要有这种异常保护的意识。
另外一种做法可以是在超过门限时,将running信号拉低,再由running&&rx_vld作为最终的vld信号,同时产生一个eop信号。
二、超短包、背靠背的支持
超短包就是包长为1,sop,eop重叠,如下图:
背靠背就是两个包之间没有间隔,如下图:
因为内部接收到数据后进行处理都是需要时间的,而这两种情况恰恰都没有提供足够的时间给到我们。
情况1,超短包的情况,可以考虑根据数据处理所需时钟周期进行打拍处理。
情况2,可以考虑在接收到每一包的eop信号后,强制拉低一个时钟周期的rdy信号来反压前级。
具体代码就懒得写了,也没什么东西;但是有没有其他更好的处理方式?
后记
这是一个爬坡的过程,需要我们不断积累经验。
欢迎分享交流。