万宁市网站建设_网站建设公司_过渡效果_seo优化
2025/12/25 5:24:04 网站建设 项目流程

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

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

  1. 模块声明与参数 (Parameters)
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)
( 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. 内部状态机定义与变量声明
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)

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. 数据校验与期望值生成
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)
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仿真效果:

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询