3. AXI4-Full 协议中的握手:AW/AR 通道的地址握手,W/R 通道的数据握手,B 通道的响应握手,乱序传输与 ID 机制

大家好,欢迎来到《接口握手信号分析与调优实战》的第三讲。今天咱们聊聊 AXI4-Full 协议里最核心的握手机制。说实话,AXI 协议在 SoC 互联里几乎是标配,但很多人只停留在「知道有五个通道」这个层面。真正调起性能来,握手时序、通道间的依赖关系、乱序传输这些才是硬骨头。

我个人习惯把 AXI 的握手分成三组来看:地址握手、数据握手、响应握手。这样思路清晰,调试时也容易定位问题。咱们一个一个来拆解。

3.1 地址握手:AW 和 AR 通道

先看写地址通道 AW 和读地址通道 AR。这两个通道的握手逻辑完全一样,只是方向不同。说白了,主机要告诉从机:「我要读写哪个地址,什么属性,多大尺寸。」

握手信号就两个:VALID 和 READY。VALID 由主机拉高,表示地址和控制信号有效;READY 由从机拉高,表示可以接收。两者同时为高时,握手成功,地址在时钟上升沿被采样。

关键点:VALID 不能依赖 READY。也就是说,主机一旦拉高 VALID,必须保持到握手完成,不能中途撤掉。这是协议强制的,我见过有新人写 RTL 时,看到 READY 没拉高就把 VALID 拉低了,结果仿真直接报协议违例。

从机这边,READY 可以提前拉高,也可以等 VALID 来了再拉高。提前拉高叫「提前握手」,好处是零等待,但可能浪费资源;等 VALID 来了再拉高叫「条件握手」,更省资源但多一个周期延迟。怎么选?看你的带宽和面积 trade-off。

我的经验:在高速设计中,我通常让从机 READY 提前拉高,除非从机内部 buffer 快满了。这样地址通道几乎零等待,吞吐率能上去。但要注意,如果多个主机同时发地址,仲裁逻辑要处理好,否则容易死锁。

3.2 数据握手:W 和 R 通道

数据通道比地址通道复杂一些,因为涉及数据宽度、字节使能、还有 last 信号。

写数据通道 W 有 WDATA、WSTRB、WLAST。WLAST 表示最后一个数据拍。读数据通道 R 有 RDATA、RRESP、RLAST。RLAST 也是最后一个数据拍。

握手规则和地址通道一样:VALID + READY 同时为高时传输。但这里有个坑:写数据通道的 WVALID 和 WREADY 握手时,WLAST 必须和最后一个数据同时有效。也就是说,最后一拍数据来的时候,WLAST 必须拉高,不能提前也不能滞后。

我曾经踩过的坑:有一次调试一个 DMA 控制器,发现写传输总是少一个 beat。查了半天,发现是 WLAST 在倒数第二拍就拉高了,导致从机以为传输提前结束。嗯,从那以后我写代码时都会加一个断言:WLAST 只在最后一拍有效,且必须和 WVALID 同时拉高。

读数据通道 R 相对简单,因为数据是从机返回的。主机只需要准备好接收即可。但要注意,RLAST 必须和最后一个数据同时有效,否则主机不知道传输何时结束。

3.3 响应握手:B 通道

写响应通道 B 是 AXI 里最容易忽略的通道。很多人觉得「写完了就完了呗,还要什么响应?」其实不然。B 通道返回写传输的结果:OKAY、EXOKAY、SLVERR、DECERR。主机必须接收这个响应,才能知道写操作是否成功。

握手规则一样:BVALID 由从机拉高,BREADY 由主机拉高。两者同时为高时,响应被接收。

这里有个重要的依赖关系:B 通道的握手必须发生在最后一个写数据握手之后。也就是说,从机不能在 WLAST 握手完成之前就返回 BVALID。这是协议规定的顺序要求。

实际项目中:我遇到过从机设计不规范,WLAST 还没握手,BVALID 就拉高了。结果主机收到响应时,写数据还没写完,导致数据错乱。所以,写响应通道的时序一定要严格遵循协议顺序。

3.4 乱序传输与 ID 机制

AXI4-Full 最强大的特性之一就是乱序传输。说白了,主机可以连续发多个地址请求,从机可以按任意顺序返回数据或响应。这靠什么实现?靠 ID 标签。

每个传输事务都有一个 ID。地址通道的 ARID 或 AWID 携带这个 ID,数据通道的 RID 或 BID 必须和地址 ID 一致。这样主机就能区分哪个数据属于哪个事务。

举个例子:主机发了两个读请求,ID 分别是 0 和 1。从机可能先返回 ID=1 的数据,再返回 ID=0 的数据。主机根据 RID 就能正确地把数据路由到对应的处理单元。

我的建议:乱序深度不是越大越好。ID 位数越多,硬件复杂度越高。我一般控制在 4-8 个 outstanding 事务,ID 用 4 位就够了。超过这个数,互联逻辑的 buffer 和仲裁器会变得很庞大,得不偿失。

另外,写事务的乱序和读事务不同。写事务的地址和数据是分开的,但同一个 ID 的写数据必须按顺序发送。也就是说,你不能先发 ID=0 的地址,再发 ID=1 的地址,然后先发 ID=1 的数据,再发 ID=0 的数据——数据必须按地址顺序来。但不同 ID 之间可以乱序。

读事务就自由多了:地址可以乱序发,数据也可以乱序回。只要 ID 匹配就行。

3.5 握手时序调优实战

说了这么多理论,来点实际的。调优握手时序,我总结了几条经验:

  • 减少地址通道的等待:让从机 READY 提前拉高,或者用寄存器切片把长路径打断。地址通道的延迟直接影响整个传输的启动时间。
  • 数据通道的背压处理:如果从机处理速度慢,WREADY 或 RREADY 会频繁拉低。这时候要考虑增加 FIFO 深度,或者用 out-of-order 来掩盖延迟。
  • 响应通道不要忽略:BREADY 必须及时拉高,否则从机可能卡住无法处理下一个写事务。我习惯让 BREADY 一直为高,除非主机内部 buffer 满了。
  • ID 管理要谨慎:不同 master 的 ID 不能冲突,同一 master 的不同事务 ID 要唯一。否则乱序回来数据会乱套。

一个真实案例:之前调一个多核 SoC,CPU 和 GPU 同时访问 DDR。CPU 用 ID=0,GPU 用 ID=1。结果发现 GPU 的读数据经常被 CPU 的数据覆盖。查了半天,是互联逻辑的 ID 重映射没做好,两个 master 的 ID 在内部被映射成了同一个值。嗯,从那以后我每次做互联设计,第一件事就是检查 ID 映射表。

最后,给大家一个简单的握手时序图,用 SVG 画的,方便理解。

AXI4-Full 握手时序示意图 CLK 地址通道 AVALID 高 高 AREADY 高 高 ✓ ✓ 数据通道 WVALID 高 高 WREADY 高 高 ✓ ✓ 响应通道 BVALID 高 BREADY 高 ✓ VALID READY 握手成功

图中展示了三个通道的握手过程。地址通道先握手,然后数据通道,最后响应通道。注意看,地址通道的 VALID 和 READY 同时为高时,握手成功(橙色圆圈标记)。数据通道和响应通道同理。

好了,这一讲的内容就到这里。AXI 的握手看似简单,但实际调起来坑不少。记住:地址通道要快,数据通道要稳,响应通道不能忘,ID 管理要小心。下一讲咱们会深入讲 AXI 的 burst 传输和地址对齐问题,到时候再聊。

可可精品资料库