AXI4协议逻辑规范以及BUG处理-FPGA常见问题社区-FPGA CPLD-ChipDebug

AXI4协议逻辑规范以及BUG处理

1AXI 握手协议规范以及BUG处理

简介

列举AXI应该遵循的逻辑规范以及一些逻辑BUG,即使是赛林丝官方的代码也要注意。

规则

AXI所需要的信号并不多,比如,TLAST(packet最后一位数据),TUSER(帧开始信号)等等。我们先集中于握手信号这个概念,把握手信号分为三类:TVALID(有效信号,表示主机开始有效传输),TREADY(就绪信号,表示从机在该时钟周期准备好接收数据),以及TDATA(数据)。

先大致了解握手信号的基础规则:

  • xVALID必须在复位后清除
  • 总线不应该变化,除非出现xVALID && xREADY逻辑,即数据传输必须在xVALID 和 xREADY同时置位时发生。
  • xVALID && xREADY逻辑期间尽量不要在此处插入其他判断逻辑以免错过握手
  • 同一个时钟周期内,xVALID和xREADY可以有先后或者同时置位,若有置位先后,那么另一个信号必须保持置位直到握手完成
  • 主机和从机接口间不应该有组合逻辑(标准中有表述)
  • 建议规则:在总线空闲状态READY应该保持高逻辑

从机逻辑示例:

  1.  
 always @(posedge ACLK)
  // Logic to determine S_AXIS_TREADY

always @(posedge ACLK)
if (S_AXIS_TVALID && S_AXIS_TREADY) // plus nothing!(有效和准备信号下不插入其他逻辑)
// Do something

 

2.出现BUG的代码(源自赛灵丝官方):

always @(posedge S_AXI_ACLK)
if (!S_AXI_ARESETN)
 // reset the circuit
else if (S_AXI_AWVALID && S_AXI_AWREADY && something_else)
 // design is already buggy

3.下面代码来自Vivado2018.3示例

 always @( posedge S_AXI_ACLK )
 begin
   if ( S_AXI_ARESETN == 1'b0 )
     begin
  // Some reset code
     end
   else
     begin
       if (~axi_awready && S_AXI_AWVALID && ~axi_awv_awr_flag)
         begin
           // Address latching code
         end
       else if (axi_wready && S_AXI_WVALID && something_else)
 // The design is now broken

虽然上面的代码示例是针对写入地址和数据通道,但它可以在任何通道上找到。这不仅包括读地址通道,还包括写确认和读返回通道。具体来说,在任何使用基本握手协议的设计中都经常会发现此错误。之所以这个错误常常出现,可能是因为 Xilinx的示例代码就是如此。

问题在于协议本身规定总线逻辑仅取决于**VALID和*READY*,如果两者都置位,那么不管其他条件是否有效,总线都应该进入下一个状态。而以上代码的逻辑带来的危害就是,当我们用这种逻辑去和其他设备的标准总线交互时,很容易错过事务。

如何避免BUG?

always @(posedge S_AXI_ACLK)
if (!S_AXI_ARESETN)
 // reset the circuit
else if (S_AXI_AWVALID && S_AXI_AWREADY && something_else)
 // design is already buggy

改为

always @(posedge S_AXI_ACLK)
if (!S_AXI_ARESETN)
 // reset the circuit
else if (S_AXI_AWVALID && S_AXI_AWREADY)
 // Design continues ...
 
always @(*)
if (S_AXI_ARESETN && S_AXI_AWREADY)
 assert(something_else);

还有一种BUG

always @(posedge S_AXI_ACLK)
if (!S_AXI_ARESETN)
 // Reset code
else if (S_AXI_AWVALID && S_AXI_AWREADY)
 // Accept a transaction
else if (S_AXI_BVALID && S_AXI_BREADY)
 // Code is now buggy
 

总体来讲,都是握手协议应该生效进入下一状态的时候,逻辑有可能会出现阻止它进入下状态的情况,国外有个博主详细讨论了这个不规范产生的BUG(这个大家可以见仁见智):

http://zipcpu.com/formal/2019/04/16/axi-mistakes.html

主机示例代码

  1.  
 // OPT_LOWPOWER is a parameter telling me when to force unused signals
 // to a known value, to reduce any unnecessary signal toggling within
 // an FPGA.
 parameter [0:0] OPT_LOWPOWER = 1'b0;

always @(posedge ACLK)
if (!ARESETN)
M_AXIS_TVALID <= 0;
else if (!M_AXIS_TVALID || M_AXIS_TREADY)
M_AXIS_TVALID <= next_valid_signal;

 

always @(posedge ACLK)
if (OPT_LOWPOWER && !ARESETN)
M_AXIS_TDATA <= 0;
else if (!M_AXIS_TVALID || M_AXIS_TREADY)
begin
M_AXIS_TDATA <= next_data;

 

if (OPT_LOWPOWER && !next_valid)
M_AXIS_TDATA <= 0;
end

 
  1. Xilinx’s AXI stream master 模版
 assign axis_tlast = (read_pointer == NUMBER_OF_ITEMS-1);

always @(posedge  ACLK)
if (!ARESETN)
axis_tlast_delay <= 1’b0;
else
axis_tlast_delay <= axis_tlast;

 

assign M_AXIS_TLAST = axis_tlast_delay;

 

图片[1]-AXI4协议逻辑规范以及BUG处理-FPGA常见问题社区-FPGA CPLD-ChipDebug

如果 M_AXIS_TVALID && !M_AXIS_TREADY 在突发长度结束的倒数第二个节拍上,则 M_AXIS_TLAST 将随后被置位,而通道已经因为违反协议而停止。那么数据数量将出错,当然也不仅只会发生在AXI上,很多工程师不太注意这些细节逻辑。

详细的协议本身请参阅官方提供的文件。

请登录后发表评论

    没有回复内容