AXI总线介绍(详解)
原文地址:https://zhuanlan.zhihu.com/p/610401819
一、什么是总线
总线就是一组统一的信号和协议,通常用于设备之间的通讯和传输
- 主设备master:主动发出请求(如 CPU)
- 从设备slave :被动相应请求(如 内存)
二、最简单的总线(同步读 SRAM – 读写数据延迟固定 1 周期 )
1. 对sram的读信号:
- – 读哪儿:RADDR ->
- – 读多少:约定一次读一个字
- – 读多久:1 周期固定延迟
- – 读了啥:RDATA <-
遵循的协议:
master(CPU)住 slave(MEM)发送读地址
-radar下个周期 slave 向 master 回复读数据 data
上述发送行为每周期都发生
结构图
只读同步总线
2. 对sram的写信号:
- 写地址:WADDR ->
- 写数据:WDATA ->
与读数据不同,写数据还需要:
并非每个周期都要写,需要写使能(读出来不想要的没关系,但是写不行):WEN ->
若要允许写指定的部分字节,需要写掩码:WMASK ->
- 写使能:WEN ->
- 写掩码:WMASK ->
写掩码代码设计
遵循的协议:
写地址waddr,写数据 wdata
并非每周期都需要写,因此需要写使能wen
为什么可以没有读使能?
状态机视角:读操作不改变电路的状态实际中一般还是有读使能,不用读的时候节省能耗
允许只写入一部分字节,因此需要写掩码。
mask用于支持CPU的sb,sh等指令
接入写控制信号的结构
可读可写的同步总线
3. 实际情况
内存使用的存储介质通常是 DRAM
– 请求从发起到完成需要多得多的时间
– 请求从发起到完成的时间不再固定
– 同步总线不再适用于 CPU 与 DRAM 之间的通信
– 我们需要异步总线
• 考虑这样一个场景 – 在某一时刻,CPU 向 DRAM 发出读请求
– 在未知的未来某个时刻,DRAM 返回了读结果
– DRAM 要如何告诉 CPU 它已经返回了读结果?
三、加入握手信号
1. 加入读操作的握手信号
由于CPU发送raddr的时刻是不确定的,MEM可以接受地址信息的时刻也是不确定的
所以添加了rvalid的信号(充当ren的作用),以及rready信号。
加入读操作的握手信号
rvalid:CPU什么时候发送请求的是有效的(不繁忙)
rready:MEM确定是可以接受这个请求(不繁忙)
新问题:
- slave读岀 rdata 的时刻无法提前确定
DRAM会定时对存储单元的电容进行充电刷新,此时读操作需要等待- master也不一定总是准备好接收
slave读出的数据例如上一次读出的数据还没用完,取决与状态机的状态
2. 改进读操作的握手信号
虽然CPU发送地址的时刻和MEM接收地址的时刻是确定的,
但是MEM何时能返回数据和CPU何时能接收这个数据是不确定的。
所以也需要给数据加入握手的信号,为了避免重名,将地址的握手信号加入前缀a。
改进读操作的握手信号
协议:
在一次读数据过程中, master和save都需要等待两次握手
master先等arready,确保slave接收读地址后,再等rvalid接收读数据
slave先等 arvalid 接收读地址,再等 rready,确保 master接收读数据
当然在RTL层面这些都是状态机
3. 加入写操作的握手信号
由于CPU发送waddr的时刻是不确定的,MEM可以接受写地址信息的时刻也是不确定的
所以添加了wvalid的信号(充当ren的作用),以及wready信号。
加入写操作的握手信号
与读操作相同,后面也需要将写地址和写数据分别进行握手。
4. 加入错误处理信号
由于读写可能出现错误,例如超出存储区间的边界,所以加入错误处理的信号
读写回复信号:
rresp:读是否成功的信号(读回复)
wresp:写是否成功的信号(写回复)
回复信号的握手:
bvalid:表示MEM是否可以反馈wresp信号给CPU
bready:表示CPU是否可以接收来自MEM的wresp信号
加入错误处理信号
如果出现了读写错误,那么可以令CPU抛出异常,然后通知软件处理。RISC-V中可抛出3种Access fault异常。
5. 遵循AXI-Lite协议的握手
第一步:将写地址和写数据分别进行握手,同时为了避免重名,将写地址的握手信号加入前缀a。
第二步:将wmask名字改成wstrb,同时进行将信号分成5个通道。
第三步:回复信号,其实就是写响应信号(是否数据已经成功写入)。
遵循AXI-Lite协议的握手
四、从同步到异步分析
1. 加入RDVALID <-
slave 告诉 master 数据读好了:RDVALID <-
– 读响应有效信号 (Read Data Valid)
– 当 RDVALID 有效时,master 才认为 RDATA 有效
读握手信号
加入,读使能信号,否则默认一直发出读请求,slave 需要许多个周期才能响应 master 的一个读请求,当未响应的请求越来越多,直至 slave 顶不住。
2. 加入RAVALID ->
所以异步总线需要读请求有效信号 (Read Address Valid)
- 读使能/读请求有效信号 RAVALID ->
只有在RAVALID拉高时,返回的数据才有效
加入读使能信号
• 若 RAVALID 在某段时间内经常为有效电平 ≈ 此前没有 RAVALID 信号时的情况
– 未响应的请求依然可能越来越多,直至缓冲区耗尽
需要新的信号通知master
3. 加入RAREADY <-
RAREADY 有效时,master 才认为 slave 可接收请求
加入握手信号RAREADY
4. 加入WAREADY <-
类似地,添加写请求就绪信号 WAREADY <-
5. 握手机制
握手信号是异步通信的基础
– 有效信号 valid:一方想发送
– 就绪信号 ready:另一方能接收
– valid && ready:数据成功进行一次传输 • 不重不漏
异步传输
当valid && ready都拉高时,master的数据已经传递给slave,如果ready信号没有拉高,说明master需要slave准备好再发送
6. 加入RDREADY、WDVALID、WDREADY
• 如果 master 也不是时时都能接收读响应
– 读响应就绪信号:RDREADY ->
• 类似地,添加写响应信号,让 master 知道写操作何时完成
– 写响应有效信号:WDVALID <-
– 写响应就绪信号:WDREADY ->
7. 我们的异步总线
一共可以分为四路信号,每一路信号都有握手
– 读请求信号
• RAVALID ->
• RAREADY <-
• RADDR ->
– 读响应信号
• RDVALID <-
• RDREADY ->
• RDARA <-
– 写请求信号
• WAVALID (wen) ->
• WAREADY <-
• WADDR ->
• WDATA ->
• WMASK ->
– 写响应信号
• WDVALID <-
• WDREADY ->
五、AXI4-Lite
AXI4-lite
两个事务
1. 读地址通道AR
读地址通道
2. 读数据通道R
读数据通道
3. 写地址通道AW
写地址通道
4. 写数据通道W
写数据通道
5. 写相应通道B
写相应通道
6. AXI4-Lite信号一览
AXI4-Lite
注意:
• 读事务和写事务分别均为顺序响应
• 写地址通道和写数据通道可以不同时有效
• 为了避免总线死锁,规定每个通道内
– valid 置有效不能依赖于
ready 是否有效
– ready 置有效可以依赖于
valid 是否有效
六、时序分析和设计
1. 握手时序
主从interface之间,输入和输出信号之间不能有组合路径。
reset时,要保证ARVALID,AWVVALID,WVALID,RVALID,BVALID信号为低。
Handshake
source不允许等到断言READY后才断言VALID。
当VALID被断言时,它必须保持断言,直到握手发生,当VALID和READY都被断言时,在上升时钟边缘。
允许destination在断言相应的READY之前等待断言VALID。
如果断言了READY,则允许在断言VALID之前取消断言READY。
握手时序图
2. 握手信号设计
AWVALID一旦断言了,就必须等slave断言AWREADY之后的一个cycle才能取消断言。(wvalid,bvalid,arvalid,rvalid相同)valid不能等ready
AWREADY默认可高可低,specification推荐默认状态为高。(arready相同)
默认为高,只需要一个cycle
默认为低,至少会有两个cycle,一个cycle用来断言awvalid,一个cycle用来断言啊我ready
默认为高,只需要一个cycle
默认为低,至少会有两个cycle
- wready,bready和rready默认值可为高
- 建议将inactive byte lane的WDATA驱动为零。(rdata相同)
3. 握手依赖关系*
Channel handshake dependencies:
read transaction handshake signal dependencies
Master 不能等待slave拉高arready再拉高arvalid
slave可以等待master拉高arvalid再拉高arready
slave可以在master拉高arvalid之前拉高arready
slave必须在arvalid和arready拉高之后才能拉高rvalid,来表明数据已经available了
slave不能等待master拉高rready再拉高rvalid
master可以等待rvalid拉高之后再拉高rready
master截图在rvalid拉高之前再拉高rready
读操作依赖
AXI3 write transaction dependencies
master不能等待slave拉高awready和wready再拉高awvalid和wvalid
slave可以等待awvalid或valid,或者等待两个都拉高再拉高awready
slave可以在awvalid或valid,或者两个拉高之前拉高awready
slave可以等待awvalid或valid,或者等待两个都拉高再拉高wready
slave可以在awvalid或valid,或者两个拉高之前拉高wready
slave必须等待wvalid和wready拉高再拉高bvalid。slave必须在wlast拉高之后再来拉高bvalid。等待是必需的,因为写响应(BRESP)必须在写transaction的最后一次数据传输之后才发出信号。
slave必须不能等待master拉高bready再拉高bvalid
master可以等待bvalid拉高再拉高bready
master可以在bvalid拉高之前拉高bready
写操作依赖
AXI4 and AXI5 write transaction respone
slave必须等待awvalid,awready,wvalid,wready拉高再拉高bvalid。
通过发出写响应,slave负责对所有后续transaction进行hazard checking危险检查。
说明axi3 slave在接收写地址之前就可以接收所有的写数据,并且提供写响应,这与axi4和axi5不兼容。
将axi3 legacy slave转换到axi4或axi5就要求有一个wrapper,
该wrapper确保在下级slave接收适当的地址之前不提供返回的写响应。
master不能等待slave拉高awready或者wready拉高再拉高awvalid或wvalid
slave可以等待拉高awvalid和wvalid之后拉高awready
slave可以在awvalid或wvalid拉高之前拉高awready
slave可以等待awvalid或wvalid,或两者都拉高再拉高wready
slave可以在awvalid和wvalid拉高之前拉高wready
slave必须等待awvalid,awready,wvalid,wready都拉高再拉高bvalid,slave也必须等待wlast拉高再拉高bvalid。
slave不能等待master拉高bready再拉高bvalid
master可以等待bvalid拉高再拉高bready
master可以在bvalid拉高之前拉高bready
写反馈依赖
4. 突发模式时序
(1)突发读
突发读时序
RVALID信号会在AR通道完成握手后拉高,等到RREADY=1时再拉低,本质不受主机影响。
(2)突发写
突发写时序
七、AXI4总线
从 AXI4-Lite 到 AXI4
1. 突发传输
• 如果我想从内存读一整页 (4K) 的内容
– 一次读 8 Bytes,则需要发送 512 次读请求
– 有没有更好的办法呢?
• 什么是突发传输
– 一段时间内,连续地传输多个地址相邻或相同的数据
从正常传输到突发传输
从图中可以看到:
突发传输的单个数据称为transfer/beat,
突发的一组数据称为burst,
图中1个brust=4个beat/transfer,这一次传输称为transaction
2. 突发三要素
(1)突发宽度
突发宽度
突发宽度AxSIZE是设置1个beat的宽度,不可超过数据总线的宽度
(2)突发类型
突发类型
WRAP:用的不是特别多
FIXED:在同一个地址中突发
INCR:在递增地址中突发
(3)突发长度
突发长度
用于一个burst中有多少个beat。
3. AXI4 的 xID 信号
xID 用途
XID 信号
AXI4 单主机传输事务规定
4. AXI 多主机
我们也可以干脆把 IF 级和 MEM 级当作是两个 master 设备!
– IF 级和 MEM 级都能读
– 只有 MEM 级才能写
多主机支持机制
- 协议规定,不同主机间的事务是独立的,没有顺序约束
- 仲裁器如何将读数据和写响应返回给正确的主机?
– 各主机保证自己的 ID 与其他主机不同 (但是对于一个主机本身,并不知道其他主机的ID)
– 仲裁器对不同主机请求的 ID 进行调整,使得即使不同主机发出的请求 ID 相同,从机看到的 ID 不同 ✔
(1)ID重命名:
- 仲裁器接收主机事务后,在原有事务 ID 附加一个 表示来源端口的前缀
- 仲裁器接收从机事务后,根据事务 ID 前缀判断应当返还给哪一个主机
- 返还给主机前,仲裁器需要将 ID 前缀去掉
– 协议建议主机端 ID 不超过 4 位
– 协议建议仲裁器为 ID 添加的前缀不超过 4 位
(2)写事务保护:
- 写数据顺序与写事务顺序一致
– 可以看作是之前单主机版本的约定的一个扩展- 一个事务内的写数据间,不能插入其他事务的数据
- 这些规定进一步保障了即使在多主机的情况下,我们也依然不需要 ` WID
(3)多主机总结
写事务需要保序传输,当master0发送写请求时,master1不可以在master0写数据之前就把数据写到slave。
读事务可以乱序,在仲裁时进行ID重命名,保证正确返还给哪一个主机
5. 窄传输
• 当本次传输的突发宽度 (AxSIZE) 小于通道本身的宽度 (假设为 size) 时,这次传输被称为窄传输
– 数据在通道上传输的位置必须与 (数据的地址) % size 保持一致• AXI4 规定: – master 必须保证 WSTRB 只在对应字节有效时为高
(1)示例1
(2)示例2
6. 非对齐传输
非对齐传输
- 起始地址AxADDR与突发宽度AxSIZE不对齐
- 可以把它变成对齐的:
- 在首个transfer填充无效数据至对齐(需要WSTRB只在对应字节有效时为高)
- 将起始地址调整为对齐的地址- 然后,问题就退化成了窄传输/正常传输
有时候非对齐时,CPU会直接抛出异常。这样非对齐就无需实现。
7. transaction的回复信号
回复信号一般在读数据通道或者写响应通道。
八、引用
总线的输入输出: https://www.bilibili.com/video/BV1PU4y1V7X3/?p=13&vd_source=bc7872f5b0b9a069b3bdaf1e9811b3cb
总线选讲: https://www.bilibili.com/video/BV1wP4y1q7fF/?vd_source=bc7872f5b0b9a069b3bdaf1e9811b3cb
正点原子:SDK篇_58~62_AXI接口简介【Xilinx】+【Vivado】+【AXI4总线】+【FPGA】:https://www.bilibili.com/video/BV1gy4y1Y7zr/?spm_id_from=333.337.search-card.all.click&vd_source=bc7872f5b0b9a069b3bdaf1e9811b3cb
跟我一起,从零开始学AXI3,连载三:https://www.bilibili.com/video/BV1kQ4y1Y7fF/?spm_id_from=333.788.recommend_more_video.-1&vd_source=bc7872f5b0b9a069b3bdaf1e9811b3cb
优秀的 Verilog/FPGA开源项目介绍(十七)- AXI: https://cloud.tencent.com/developer/article/1954825?areaSource=102001.17&traceId=0S3pUBzHHWk6HW4GQeXNF