手把手教你用Verilog实现AXI-Lite从机接口(附完整代码与仿真)

从零构建你的第一个AXI-Lite从机:协议、代码与仿真实战

很多刚开始接触FPGA片上系统设计的工程师,一看到AXI总线协议文档里那几十个信号和复杂的时序图,心里就有点发怵。我刚开始接触Zynq平台的时候也是这样,总觉得这东西太“高级”了,应该是那些资深架构师才需要掌握的内容。但后来在实际项目中,当我需要为自定义的硬件加速器添加一个寄存器配置接口时,才发现AXI-Lite其实是我们最常打交道、也最容易上手的一种总线协议。

如果你正在设计一个需要被处理器访问的FPGA模块——比如一个自定义的DMA控制器、一个图像处理流水线的配置寄存器组,或者任何需要软件进行参数控制的硬件逻辑——那么掌握AXI-Lite从机接口的实现几乎是必经之路。与完整的AXI4协议相比,AXI-Lite做了大量简化:它不支持突发传输,每次只能读写一个数据;数据位宽固定为32位或64位;没有缓存和独占访问这些复杂机制。正是这些简化,使得我们可以用相对较少的逻辑资源,实现一个稳定可靠的处理器外设接口。

这篇文章不会只是给你一段“可以用的”模板代码然后让你照搬。我会带你从协议的核心握手机制开始理解,一步步推导出每个always块应该怎么写,最后用ModelSim仿真验证整个设计。当你跟着走完这个过程,你会真正理解为什么代码要这样写,而不仅仅是记住了一段可以复用的Verilog。

1. 理解AXI-Lite:握手、通道与依赖关系

在开始写任何代码之前,我们需要先搞清楚AXI-Lite协议到底规定了什么。很多人一上来就研究信号列表,记了一堆AWADDR、WDATA、BRESP之类的名字,但真正关键的其实是这些信号之间的握手协议依赖关系

1.1 核心握手机制:VALID与READY的舞蹈

AXI-Lite的每个通道都使用一对VALID/READY信号进行握手。这种设计非常巧妙:VALID由数据发送方控制,表示“我这里有有效数据”;READY由数据接收方控制,表示“我现在可以接收数据”。只有当VALID和READY同时为高的时钟上升沿,数据传输才真正完成。

// 这是一个概念性的握手示例,不是实际代码
// 在时钟上升沿检查:
if (VALID && READY) begin
    // 数据在这一刻被捕获
    data_latched <= data_to_transfer;
end

这种双向握手机制让通信双方都能控制传输速率。如果接收方还没准备好(READY=0),发送方可以保持VALID=1等待;如果发送方还没数据(VALID=0),接收方也可以提前拉高READY表示“我准备好了,你随时可以发”。

注意:在实际的AXI-Lite从机设计中,我们通常会让READY信号的生成逻辑稍微复杂一些,因为它需要根据协议规定的依赖关系来决定何时可以拉高。

1.2 五个通道的分工

AXI-Lite将一次完整的传输分解到五个独立的通道中,这种分离设计是它高性能的基础:

通道名称 方向(从机视角) 承载信息 关键信号
写地址通道 输入 要写入的寄存器地址 AWADDR, AWVALID, AWREADY
写数据通道 输入 要写入的数据 WDATA, WSTRB, WVALID, WREADY
写响应通道 输出 写操作是否成功 BRESP, BVALID, BREADY
读地址通道 输入 要读取的寄存器地址 ARADDR, ARVALID, ARREADY
读数据通道 输出 读取到的数据 RDATA, RVALID, RREADY

这里有个容易混淆的点:写操作需要三个通道协同工作(地址、数据、响应),而读操作只需要两个通道(地址、数据),因为读响应信息被合并到了读数据通道的RRESP信号中。

1.3 关键的依赖关系:谁必须等谁

协议文档中最让人头疼的部分可能就是那些依赖关系图了。但如果你理解了背后的逻辑,其实很简单:协议要防止死锁,确保传输能顺利进行

对于写操作,协议规定:

  1. 主机不能等待从机的READY信号——主机想写数据时,必须主动拉高VALID,不能“等从机准备好”
  2. 从机可以等待主机的VALID信号——从机可以等看到VALID再拉高READY,也可以提前拉高READY
  3. 写响应(BVALID)必须在地址和数据都传输完成后才能拉高

用更直白的话说:写的时候,主机要“主动伸手”,从机可以“等着被握”,也可以“主动伸手”。但响应的时候,角色互换,从机必须“主动伸手”告诉主机“我写完了”。

读操作的依赖关系类似,但更简单一些:

  1. 主机不能等待从机的ARREADY——读地址通道上,主机要先伸手
  2. 从机必须等收到读地址后,才能拉高RVALID——不能还没收到地址就说“数据准备好了”
  3. 从机不能等待主机的RREADY——数据准备好后,从机要主动伸手

这些依赖关系会直接体现在我们的状态机设计里。比如,如果我们违反了“从机不能等待主机的RREADY”这条规则,就可能在某些情况下造成死锁。

2. 设计思路:从协议到代码的转换

现在我们已经理解了协议的基本规则,接下来要把这些规则转换成具体的Verilog设计。我会按照实际开发的思考过程来讲解,而不是直接抛给你一段完整的代码。

2.1 写操作的关键问题

当你开始设计写通道时,需要回答三个核心问题:

第一,什么时候可以捕获写地址?

根据协议,写地址通道的握手可以独立发生。但一个更实用的设计是:只有当写地址和写数据都有效时,才认为这是一次有效的写请求。这样设计可以简化状态管理,因为AXI-Lite不支持突发传输,每次写操作都对应一个地址和一个数据。

// 判断是否发生有效的写传输
wire write_transfer_happening = (s_axi_awvalid && axi_awready && 
                                 s_axi_wvalid && axi_wready);

第二,如何处理WSTRB信号?

WSTRB(Write Strobe)信号指示了WDATA中哪些字节是有效的。对于32位数据宽度,WSTRB是4位,每位对应一个字节:

WSTRB位 对应的数据字节
[0] WDATA[7:0]
[1] WDATA[15:8]
[2] WDATA[23:16]
[3] WDATA[31:24]

如果WSTRB[n]=1,表示WDATA对应的字节应该被写入寄存器;如果为0,则保持寄存器中原有的值不变。这种设计允许主机

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值