目录
1. 概述
2. IP Packager 重要参数
2.1 参数说明
3. AXI4 Lite 写操作逻辑
3.1 写数据请求发起
3.2 写响应通道握手
3.3 从机锁存数据
3.4 地址和数据处理
3.5 地址空间详解
4. 写入和读取请求
4.1 寄存器写入逻辑
4.2 写操作握手
4.3 读请求发起
4.4 读操作握手
5. 读数据请求的处理逻辑
5.1 读请求的接收与响应
5.2 读响应的完成与握手
5.3 读取数据的选择与输出
5.4 读数据的锁存
1. 概述
- 在Vivado中自定义IP核是一个常见的任务,特别是在开发Zynq平台时。
- 自定义IP核可以通过Vivado设计套件中的工具来创建、打包和重用。通常,
- 自定义IP核可以与DMA核相连,以实现数据传输和处理。
- 在Vivado中创建自定义IP核涉及使用Create and Package IP wizard等工具,同时也可以使用AXI协议来定义IP核的接口。
- 通过自定义IP核,开发人员可以实现特定功能的硬件加速,以提高系统性能和效率。
2. IP Packager 重要参数
2.1 参数说明
// Width of S_AXI data bus
parameter integer C_S_AXI_DATA_WIDTH = 32,
// Width of S_AXI address bus
parameter integer C_S_AXI_ADDR_WIDTH = 4
定义了4个32bit位宽的寄存器
// 主设备将启动对从设备的读写事务,基地址在此处作为参数指定。
parameter integer C_M_AXI_ADDR_WIDTH = 32,// 主设备发出写数据并接受读数据,其中数据总线的宽度为C_M_AXI_DATA_WIDTH
parameter integer C_M_AXI_DATA_WIDTH = 32,// 事务数量是指主设备将执行的写和读事务的数量
parameter integer C_M_TRANSACTIONS_NUM = 4,
3. AXI4 Lite 写操作逻辑
// 1.从写地址通道空闲 2.主写地址通道就绪 3.主写数据通道就绪 4.从aw_en就绪; 此条件为主机发起AXI写数据请求
if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)// 2.主写响应通道忙 <- 1.从写响应通道就绪; 此条件为写响应通道握手
if (S_AXI_BREADY && axi_bvalid)// 1.从写数据通道忙 2.主写数据通道就绪 3.从写地址通道忙 4.主写地址通道就绪;此条件为从机准备锁存数据
assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;//slv_reg_wren, slave register write enable// ADDR_LSB参数,取决于AXI数据位宽,32bit/64bit分别对应AXI每时钟周期传输4bytes/8bytes,分别占用2bit/3bit地址空间
localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1;
localparam integer OPT_MEM_ADDR_BITS = 1; // OPT_MEM_ADDR_BITS参数由用户定义的寄存器数量决定reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr; //用于锁存AXI总线的AXI_AWADDR,即写地址通道的地址信息case ( axi_awaddr[ ADDR_LSB + OPT_MEM_ADDR_BITS : ADDR_LSB ] ) // 下一页有详解2'h0:// for在always块中,用于生成多份代码for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )if ( S_AXI_WSTRB[byte_index] == 1 ) begin// Respective byte enables are asserted as per write strobes // Slave register 0slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];end
3.1 写数据请求发起
首段代码检查了是否满足主机(通常是处理器)向从机(如存储器或外设)发起AXI写数据请求的条件。这些条件包括:
- 写地址通道(AW通道)未就绪 (~axi_awready)
- 从机写地址有效 (S_AXI_AWVALID)
- 从机写数据有效 (S_AXI_WVALID)
- 写使能 (aw_en) 信号就绪
当这些条件同时满足时,表示主机准备好发送写地址和写数据到从机。
3.2 写响应通道握手
检查是否满足以下条件:
- 主机准备接收写响应 (S_AXI_BREADY)
- 从机的写响应有效 (axi_bvalid)
当这些条件同时满足时,表示写操作已完成,主机和从机之间完成了一次写响应通道的握手。
3.3 从机锁存数据
第三段代码通过assign语句定义了一个条件,用于判断从机是否准备好锁存(存储)数据。这个条件包括:
- 写数据通道(W通道)就绪 (axi_wready)
- 主机写数据有效 (S_AXI_WVALID)
- 写地址通道(AW通道)就绪 (axi_awready)
- 主机写地址有效 (S_AXI_AWVALID)
当这些条件同时满足时,表示从机准备好锁存从主机发来的写数据。
3.4 地址和数据处理
代码中定义了一些参数来处理地址和数据宽度的不同配置,例如ADDR_LSB根据AXI数据位宽(32位或64位)来确定地址的最低有效位,这对于确定如何根据地址访问或修改数据很重要。
接着,使用case语句和一个循环来处理不同地址下的数据写入操作。这里,根据地址和写入使能(S_AXI_WSTRB)来确定哪些字节需要被更新。对于选定的地址,循环遍历所有的数据字节,如果相应的写入使能位被设置,则更新从机寄存器(slv_reg0)中对应的字节。
3.5 地址空间详解
4. 写入和读取请求
详解case,以数据位宽32bit,用户寄存器数量4个,为例:
case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
case ( axi_awaddr[3:2] ) // axi_awaddr[3:2] 有两位地址空间,最多可以容纳4个用户定义寄存器,本例中刚好为4个;2‘h0: // 类似于DDR,AXI数据位每8bit有一个strobe信号if ( S_AXI_WSTRB[0] == 1 ) slv_reg0[ 7: 0] <= S_AXI_WDATA[ 7: 0];if ( S_AXI_WSTRB[1] == 1 ) slv_reg0[15: 8] <= S_AXI_WDATA[15: 8];if ( S_AXI_WSTRB[2] == 1 ) slv_reg0[23:16] <= S_AXI_WDATA[23:16];if ( S_AXI_WSTRB[3] == 1 ) slv_reg0[31:24] <= S_AXI_WDATA[31:24];2'h1: …2'h2: …2'h3: …
// 以上case段功能:根据 AXI 总线中的 S_AXI_AWADDR (写地址通道的地址信息)更新从机对应地址寄存器的值,即数据锁存,
// 用户逻辑,则可由锁存的数据,来实现具体逻辑层操作。// 1.从写地址通道忙 2.主写地址通道就绪 3.从写响应通道空闲 4.从写数据通道忙 5.主写数据通道就绪; 写地址、写数据均握手
if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID) //此条件为从机锁存数据完毕// 1.从读地址通道空闲 2.主读地址通道就绪; 此条件为主机发起AXI读数据请求
if (~axi_arready && S_AXI_ARVALID) //将执行地址锁存// 1.主读地址通道忙 2.从读地址通道就绪 3.从读数据通道未就绪 ; 此条件为读地址通道握手,从机发送AXI读数据通道请求
if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)
4.1 寄存器写入逻辑
通过case语句,根据写地址(axi_awaddr),决定更新哪一个用户定义的寄存器(slv_reg0到slv_reg3)。每个寄存器的更新是基于写数据(S_AXI_WDATA)和写入使能(S_AXI_WSTRB)信号。这里,S_AXI_WSTRB信号用于控制哪些字节应被写入,类似于动态随机存取存储器(DDR)中的字节使能信号。
以32位数据位宽的情况为例,寄存器写入逻辑支持最多4个用户定义寄存器。写地址信号的特定位(在这个例子中是axi_awaddr[3:2])用于选择具体的寄存器进行操作。
4.2 写操作握手
当写地址通道(AW)就绪且有效,写数据通道(W)就绪且有效,且写响应通道(B)未被占用时,表示一个写操作已经完成握手,数据可以被锁存到从机的寄存器中。这是一个标准的写操作流程,包括发送写地址、写数据和接收写响应。
4.3 读请求发起
当读地址通道(AR)空闲且读地址有效时,表示主机发起了一个AXI读数据请求。此时,从机将锁存读请求的地址,准备后续的数据传输。
4.4 读操作握手
当读地址通道就绪且有效,但读数据通道(R)未就绪时,表示读地址通道已经完成握手,从机准备发送读数据请求。这是读操作的一个关键步骤,确保了数据能够从指定地址被读出并传输给请求方。
5. 读数据请求的处理逻辑
5.1 读请求的接收与响应
从机接收到主机的读请求并准备好响应的逻辑,当以下条件同时满足时:
- 读地址通道就绪(axi_arready)
- 主机的读地址有效(S_AXI_ARVALID)
- 读数据通道未就绪(~axi_rvalid)
此时,从机将axi_rvalid标志置为1,表示从机已经准备好发送读数据。同时,axi_rresp被设置为0,表示读操作成功,无错误。
5.2 读响应的完成与握手
当从机已经标记读数据通道为就绪(axi_rvalid为1),且主机准备接收数据(S_AXI_RREADY)时,表示读响应的握手成功。
此时,从机将axi_rvalid标志拉低,完成一次读操作的数据传输过程。
5.3 读取数据的选择与输出
通过一个always块和case语句,根据读请求的地址(axi_araddr),选择相应的从机寄存器(slv_reg0到slv_reg3)中的数据准备输出。这里,地址的特定位用于选择具体的寄存器。
5.4 读数据的锁存
通过slv_reg_rden信号,当从机准备好读数据时,选中的寄存器数据(reg_data_out)被锁存到axi_rdata中,准备通过AXI接口发送给主机。slv_reg_rden信号的条件与读请求接收与响应的条件一致,确保了数据的正确输出。