3. AXI握手协议:VALID/READY握手机制、依赖关系、传输握手过程

各位同学,咱们今天聊聊AXI总线里最基础、也最核心的东西——握手协议。说白了,就是数据怎么在主机和从机之间“打个招呼”,然后顺利传过去。

我刚开始接触AXI的时候,觉得这玩意儿不就是两根信号线嘛,VALID和READY,有啥好讲的?后来做项目踩了坑才发现,这里面的门道可真不少。你想想看,一个复杂的SoC里,几十个Master和Slave同时跑,要是握手没搞好,轻则性能下降,重则数据出错,那可就麻烦了。

3.1 VALID/READY握手机制

AXI的传输,靠的就是VALID和READY这对“黄金搭档”。

  • VALID:由发送方(Source)驱动。表示“我这边数据/地址/控制信号已经准备好了,你随时可以拿走”。
  • READY:由接收方(Destination)驱动。表示“我现在有空,可以接收数据了”。

只有当VALID和READY同时为高的时候,传输才算真正发生。这个时刻,我们称之为“握手成功”。

核心原则:VALID信号一旦拉高,必须保持到握手成功,不能中途变卦。READY信号则可以随时拉高拉低,比较灵活。

我个人习惯把VALID看作是“发送方的承诺”,READY是“接收方的意愿”。只有双方都点头,交易才能达成。

3.2 依赖关系

这里有个容易搞混的地方——VALID和READY之间有没有依赖关系?

答案是:有,但很微妙。

  • VALID不能依赖READY:发送方不能等看到READY为高才去拉VALID。换句话说,VALID的产生逻辑里,不能有READY信号参与。这是协议明确规定的。
  • READY可以依赖VALID:接收方可以等看到VALID为高,再决定是否拉高READY。这在设计中很常见,比如从机还没准备好,看到主机发请求了,才赶紧准备。

我曾经在一个项目中,为了省逻辑,让VALID的产生条件里加了个READY的判断。结果仿真没问题,上板子就出错了。后来查了半天,发现是综合工具把组合逻辑环路优化掉了,导致握手时序混乱。从那以后,我再也不敢这么干了。

3.3 传输握手过程

握手过程有三种情况,咱们一个一个来看。

3.3.1 仅VALID先有效

这是最常见的情况。发送方先拉高VALID,等待接收方就绪。接收方准备好了,拉高READY,握手成功。

// 伪代码示例:发送方
always @(posedge clk) begin
  if (!ready) begin
    valid <= 1;  // 先拉高VALID
    data <= tx_data;
  end else begin
    valid <= 0;  // 握手成功,拉低VALID
  end
end

// 接收方
always @(posedge clk) begin
  if (valid && !ready) begin
    ready <= 1;  // 看到VALID,拉高READY
  end else begin
    ready <= 0;
  end
end

这种模式下,发送方需要等待接收方。如果接收方处理速度慢,就会产生气泡(bubble),影响吞吐量。

3.3.2 仅READY先有效

接收方提前拉高READY,表示“我随时可以收”。发送方准备好后,拉高VALID,握手瞬间完成。

// 发送方
always @(posedge clk) begin
  if (ready) begin
    valid <= 1;  // 看到READY,拉高VALID
    data <= tx_data;
  end else begin
    valid <= 0;
  end
end

// 接收方
always @(posedge clk) begin
  ready <= 1;  // 一直准备好
end

这种模式适合接收方处理能力很强的场景,比如一个深度很大的FIFO。发送方只要数据准备好了,就能立刻传过去,延迟最低。

小技巧:在设计高性能AXI互联时,我建议把Slave端的READY默认拉高。这样Master发数据时,只要VALID有效,一拍就能传过去,效率最高。当然,前提是Slave确实能处理这个速率。

3.3.3 同时有效

VALID和READY在同一拍同时拉高。这是最理想的情况,传输一拍完成,没有任何等待。

// 发送方和接收方一拍搞定
// 发送方:valid <= 1; data <= tx_data;
// 接收方:ready <= 1;
// 握手成功!

嗯,这里要注意,同时有效并不意味着双方事先商量好了。而是说,发送方准备好了,接收方也恰好准备好了,一拍即合。

3.4 握手时序图

光说可能不够直观,我画了个时序图,大家看看就明白了。

AXI握手协议时序图 CLK T1 T2 T3 T4 T5 T6 T7 VALID READY DATA VALID拉高 READY拉高 握手成功! 图例 VALID READY DATA

从时序图可以看到,VALID在T2时刻拉高,READY在T4时刻拉高。到了T5时刻,两者同时为高,握手成功,数据被接收方取走。

3.5 实际设计中的注意事项

讲完了理论,咱们聊聊实际设计中容易踩的坑。

避坑指南:

  • 组合逻辑环路:VALID和READY之间不能有组合逻辑环路。比如,VALID = some_condition & READY,这就是个环路,仿真可能没问题,但综合会出问题。
  • VALID过早拉低:VALID一旦拉高,必须保持到握手成功。如果中途拉低,接收方可能只收到部分数据,导致传输错误。
  • READY抖动:READY可以随时变化,但不要频繁抖动。否则发送方会很难判断什么时候该发数据,影响性能。

我的经验:在设计AXI互联时,我习惯在VALID路径上加一级寄存器,避免组合逻辑过长。虽然多了一拍延迟,但时序收敛容易得多。对于高性能设计,可以用pipeline寄存器来补偿这一拍。

3.6 总结

AXI的握手协议,说白了就是VALID和READY的“双人舞”。

  • VALID是发送方的承诺,READY是接收方的意愿。
  • 两者同时为高,传输才发生。
  • VALID不能依赖READY,READY可以依赖VALID。
  • 三种握手过程:仅VALID先有效、仅READY先有效、同时有效。

嗯,掌握了这些,AXI握手这块你就基本过关了。下一节咱们聊聊通道之间的关系,那才是真正体现AXI设计精髓的地方。


可可精品资料库