FPGA教程系列-Vivado AXI4-Lite master 测试

FPGA教程系列-Vivado AXI4-Lite master 测试

Master与Slave类似,对该功能进行一个简单的分析:

  1. 模块声明与参数 (Parameters)
verilog 复制代码
module myip_axi_lite_master_master_lite_v1_0_M00_AXI #
(
    parameter  C_M_START_DATA_VALUE    = 32'hAA000000, // 测试数据的起始值
    parameter  C_M_TARGET_SLAVE_BASE_ADDR = 32'h40000000, // 目标从机的基地址
    parameter integer C_M_AXI_ADDR_WIDTH = 32,        // 地址位宽
    parameter integer C_M_AXI_DATA_WIDTH = 32,        // 数据位宽
    parameter integer C_M_TRANSACTIONS_NUM = 4        // 测试读写的次数(默认做4次读写)
)

定义了模块的可配置参数。

关键点

  • C_M_TARGET_SLAVE_BASE_ADDR:这个非常重要, Master 发出的所有地址都会加上这个基地址。如果你的 Slave 挂载在 0x40000000,这里就必须填对,否则 Master 会读写到错误的地址空间。
  • C_M_TRANSACTIONS_NUM:决定了这次测试会连续写几个字,再读几个字。
  1. 端口定义 (Ports)
verilog 复制代码
(
    input wire  INIT_AXI_TXN,  // 用户信号:拉高此信号,开始一次完整的 读写测试
    output reg  ERROR,         // 用户信号:如果读回数据不对,输出1
    output wire  TXN_DONE,     // 用户信号:测试完成信号
    input wire  M_AXI_ACLK,    // AXI 时钟
    input wire  M_AXI_ARESETN, // AXI 复位(低电平有效)
    // ... 下面是标准的 AXI4-Lite 五个通道的信号 ...
    // 写地址通道 (AW): M_AXI_AWADDR, M_AXI_AWVALID, M_AXI_AWREADY...
    // 写数据通道 (W):  M_AXI_WDATA, M_AXI_WSTRB, M_AXI_WVALID...
    // 写响应通道 (B):  M_AXI_BRESP, M_AXI_BVALID...
    // 读地址通道 (AR): M_AXI_ARADDR, M_AXI_ARVALID...
    // 读数据通道 (R):  M_AXI_RDATA, M_AXI_RVALID...
)

定义了物理接口。作为 Master,输出是以 VALID​ 结尾的信号(如 AWVALID​),输入是以 READY​ 结尾的信号(如 AWREADY)。这与 Slave 刚好相反。

  1. 内部状态机定义与变量声明
verilog 复制代码
localparam [1:0] IDLE = 2'b00, 
        INIT_WRITE   = 2'b01, // 状态:正在写
        INIT_READ = 2'b10,    // 状态:正在读
        INIT_COMPARE = 2'b11; // 状态:正在比较结果
// ...
reg [1:0] mst_exec_state; // 主控流程状态机
reg [1:0] state_write;    // 写通道状态机
reg [1:0] state_read;     // 读通道状态机

定义了整个模块的控制逻辑。这里有三个层级的状态机:

  1. mst_exec_state(主控) :负责宏观流程(闲置 -> 写全套 -> 读全套 -> 比较 -> 结束)。

  2. state_write(写底层) :负责 AXI 写通道的具体握手细节。

  3. state_read(读底层) :负责 AXI 读通道的具体握手细节。

  4. I/O 连接 (Assigns)

verilog 复制代码
assign M_AXI_AWADDR = C_M_TARGET_SLAVE_BASE_ADDR + axi_awaddr; // 基地址 + 偏移量
assign M_AXI_WDATA  = axi_wdata;
assign M_AXI_WSTRB  = 4'b1111; // 这里的 1111 表示 32位数据全部有效(写全字)
assign init_txn_pulse = (!init_txn_ff2) && init_txn_ff; // 产生一个单周期的脉冲信号

将内部寄存器连接到输出端口。init_txn_pulse​ 是通过检测 INIT_AXI_TXN 输入信号的上升沿生成的。这意味着给一个高电平开关,内部只会触发一次启动脉冲。

  1. 写通道状态机 (Write State Machine)

IDLE 状态

  • 等待 init_txn_pulse 且主状态机进入 INIT_WRITE
  • 一旦触发,立即拉高 axi_awvalid (写地址有效) 和 axi_wvalid (写数据有效)。这是一个简化的设计,为了效率,它同时发起了地址和数据。

WADDR 状态 (写地址)

  • 等待从机回复 M_AXI_AWREADY
  • 处理逻辑 :这个状态机比较激进。它会检查从机是否已经准备好接收数据 (M_AXI_WREADY)。
  • 如果地址和数据都握手成功,它会更新地址 (+4) 和数据 (+1),并检查是否写够了次数 (write_index)。
  • 如果还没写完,继续保持在 WADDR 发送下一个。
  • 如果只是地址握手了但数据没握手,它会跳到 WDATA 状态去专门等数据握手。

WDATA 状态 (写数据)

  • 当进入这个状态,说明地址已经发过去了,现在只等从机接收数据。
  • 一旦 M_AXI_WREADY 有效,完成数据传输,跳转回 WADDR 或者结束。
  1. 读通道状态机 (Read State Machine)

IDLE 状态

  • 等待主控状态机发出 INIT_READ 命令。
  • 触发后,拉高 axi_arvalid (读地址有效),进入 RADDR

RADDR 状态 (发读地址)

  • 等待从机回复 M_AXI_ARREADY
  • 握手成功后,拉低 arvalid,拉高 axi_rready (表示主机准备好收数据了),地址加 4,跳转到 RDATA

RDATA 状态 (收读数据)

  • 等待从机发送数据有效信号 M_AXI_RVALID
  • 握手成功后,读取数据,计数器 read_index 加 1。
  • 如果没读完,跳回 RADDR 发起下一次读地址请求;如果读完了,回 IDLE。

区别:写操作是地址和数据几乎同时发出的(为了快),而读操作是严格的"先发地址 -> 再等数据"的串行流程。

  1. 数据校验与期望值生成
verilog 复制代码
always @(posedge M_AXI_ACLK)
begin
  // ...
  else if (M_AXI_RVALID && axi_rready) // 每当成功读到一个数据
    begin
      expected_rdata <= C_M_START_DATA_VALUE + read_index + 1; // 生成期望值
    end
end

Master 内部自己算一个"应该读到的数据"。因为写入时是 Start_Value + 0​, +1​, +2... 所以读出时也按这个规律比对。

  1. 主控状态机 (Master Execution FSM)
verilog 复制代码
case (mst_exec_state)
  IDLE: 
      if (init_txn_pulse) mst_exec_state <= INIT_WRITE; // 收到开始信号,去写
  INIT_WRITE:
      if (writes_done) mst_exec_state <= INIT_READ;     // 写完了,去读
  INIT_READ:
      if (reads_done) mst_exec_state <= INIT_COMPARE;   // 读完了,去比较
  INIT_COMPARE:
      begin
          ERROR <= error_reg; // 输出错误标志
          compare_done <= 1'b1; // 输出完成标志
          mst_exec_state <= IDLE; // 回到空闲,等待下一次触发
      end
endcase
  • 功能:这就是整个 IP 的总指挥。它协调读写顺序。
  1. 错误检测逻辑

代码末尾有几个小的 always 块:

  1. writes_done / reads_done :判断计数器是否达到预设的 TRANSACTIONS_NUM
  2. read_mismatch :实时比较总线上的 RDATA 和内部的 expected_rdata。如果不相等,置位。
  3. error_reg :捕捉任何错误(读写响应错误 BRESP/RRESP 非 0,或者数据校验错误)。

仿真:

AXI_VIP_IP仿真效果:

精髓还是一句话,握手成功再进行数据通信。

相关推荐
Wishell20151 天前
FPGA教程系列-Vivado AXI4-Lite slave 测试
仿真
Wishell20152 天前
FPGA教程系列-Vivado AXI4-Lite接口
仿真
民乐团扒谱机5 天前
【微实验】仿AU音频编辑器开发实践:从零构建音频可视化工具
算法·c#·仿真·audio·fft·频谱
Wishell20155 天前
FPGA教程系列-Vivado AXI4-Stream Data FIFO核解读测试
仿真
Wishell20158 天前
FPGA教程系列-Vivado AXI4-Stream接口解读
仿真
民乐团扒谱机9 天前
十字路口交通信号灯控制器设计(Multisim 电路 + Vivado 仿真)
单片机·fpga开发·verilog·状态机·仿真·时序逻辑·multism
Wishell20159 天前
FPGA教程系列-Vivado AXI4-Stream自定义IP核
仿真
智行众维11 天前
【用户心得】SCANeR™Studio学习笔记(六):人因工程Pack——一站式搞定驾驶模拟的多模态数据同步
笔记·学习·自动驾驶·汽车·仿真·scaner·人因工程
世冠科技11 天前
建模仿真技术成为汽车产教融合新引擎,世冠科技董事长李京燕发表主题报告
仿真·国产软件