我这里一共调用了两个自定义的IP都是基于axi_lite的IP核,一个是主机master一个是从机slave,然后
将这两个调用的IP例化到一个新创建的fpga工程,最好写一个仿真脚本让这个master主机对这个从机
slave进行读写。
链接:https://pan.baidu.com/s/1WFCazNaUaXBwKuJtAZNKZQ 密码:ex8l
主机:
从机:
将master和slave都例化到fpga工程的顶层文件如下图所示
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2018/05/21 10:27:22 // Design Name: // Module Name: test_axi // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module test_axi( input axi_aclk, input axi_aresetn, input app_txn, output state_err, output state_done ); parameter integer C_AXI_ADDR_WIDTH = 32; parameter integer C_AXI_DATA_WIDTH = 32; wire w_err; // 状态指示,出现错误 wire w_txn_done; // 状态指示,发送完毕 assign state_err = w_err; assign state_done = w_txn_done; wire [C_AXI_ADDR_WIDTH-1 : 0] axi_AWADDR; // AXI总线信号:AWADDR wire [2 : 0] axi_AWPROT; // AXI总线信号:AWPROT wire axi_AWVALID; // AXI总线信号:AWVALID wire axi_AWREADY; // AXI总线信号:AWREADY wire [C_AXI_DATA_WIDTH-1 : 0] axi_WDATA; // AXI总线信号:WDATA wire [C_AXI_DATA_WIDTH/8-1 : 0] axi_WSTRB; // AXI总线信号:WSTRB wire axi_WVALID; // AXI总线信号:WVALID wire axi_WREADY; // AXI总线信号:WREADY wire [1 : 0] axi_BRESP; // AXI总线信号:BRESP wire axi_BVALID; // AXI总线信号:BVALID wire axi_BREADY; // AXI总线信号:BREADY wire [C_AXI_ADDR_WIDTH-1 : 0] axi_ARADDR; // AXI总线信号:ARADDR wire [2 : 0] axi_ARPROT; // AXI总线信号:ARPROT wire axi_ARVALID; // AXI总线信号:ARVALID wire axi_ARREADY; // AXI总线信号:ARREADY wire [C_AXI_DATA_WIDTH-1 : 0] axi_RDATA; // AXI总线信号:RDATA wire [1 : 0] axi_RRESP; // AXI总线信号:RRESP wire axi_RVAILD; // AXI总线信号:RVAILD wire axi_RREADY; // AXI总线信号:RREADY myip_master_0 u1 ( .m00_axi_awaddr(axi_AWADDR), // output wire [31 : 0] m00_axi_awaddr .m00_axi_awprot(axi_AWPROT), // output wire [2 : 0] m00_axi_awprot .m00_axi_awvalid(axi_AWVALID), // output wire m00_axi_awvalid .m00_axi_awready(axi_AWREADY), // input wire m00_axi_awready .m00_axi_wdata(axi_WDATA), // output wire [31 : 0] m00_axi_wdata .m00_axi_wstrb(axi_WSTRB), // output wire [3 : 0] m00_axi_wstrb .m00_axi_wvalid(axi_WVALID), // output wire m00_axi_wvalid .m00_axi_wready(axi_WREADY), // input wire m00_axi_wready .m00_axi_bresp(axi_BRESP), // input wire [1 : 0] m00_axi_bresp .m00_axi_bvalid(axi_BVALID), // input wire m00_axi_bvalid .m00_axi_bready(axi_BREADY), // output wire m00_axi_bready .m00_axi_araddr(axi_ARADDR), // output wire [31 : 0] m00_axi_araddr .m00_axi_arprot(axi_ARPROT), // output wire [2 : 0] m00_axi_arprot .m00_axi_arvalid(axi_ARVALID), // output wire m00_axi_arvalid .m00_axi_arready(axi_ARREADY), // input wire m00_axi_arready .m00_axi_rdata(axi_RDATA), // input wire [31 : 0] m00_axi_rdata .m00_axi_rresp(axi_RRESP), // input wire [1 : 0] m00_axi_rresp .m00_axi_rvalid(axi_RVAILD), // input wire m00_axi_rvalid .m00_axi_rready(axi_RREADY), // output wire m00_axi_rready .m00_axi_aclk(axi_aclk), // input wire m00_axi_aclk .m00_axi_aresetn(axi_aresetn), // input wire m00_axi_aresetn .m00_axi_init_axi_txn(app_txn), // input wire m00_axi_init_axi_txn .m00_axi_error(w_err), // output wire m00_axi_error .m00_axi_txn_done(w_txn_done) // output wire m00_axi_txn_done ); myip_Slave_0 u2 ( .s00_axi_awaddr(axi_AWADDR), // input wire [3 : 0] s00_axi_awaddr .s00_axi_awprot(axi_AWPROT), // input wire [2 : 0] s00_axi_awprot .s00_axi_awvalid(axi_AWVALID), // input wire s00_axi_awvalid .s00_axi_awready(axi_AWREADY), // output wire s00_axi_awready .s00_axi_wdata(axi_WDATA), // input wire [31 : 0] s00_axi_wdata .s00_axi_wstrb(axi_WSTRB), // input wire [3 : 0] s00_axi_wstrb .s00_axi_wvalid(axi_WVALID), // input wire s00_axi_wvalid .s00_axi_wready(axi_WREADY), // output wire s00_axi_wready .s00_axi_bresp(axi_BRESP), // output wire [1 : 0] s00_axi_bresp .s00_axi_bvalid(axi_BVALID), // output wire s00_axi_bvalid .s00_axi_bready(axi_BREADY), // input wire s00_axi_bready .s00_axi_araddr(axi_ARADDR), // input wire [3 : 0] s00_axi_araddr .s00_axi_arprot(axi_ARPROT), // input wire [2 : 0] s00_axi_arprot .s00_axi_arvalid(axi_ARVALID), // input wire s00_axi_arvalid .s00_axi_arready(axi_ARREADY), // output wire s00_axi_arready .s00_axi_rdata(axi_RDATA), // output wire [31 : 0] s00_axi_rdata .s00_axi_rresp(axi_RRESP), // output wire [1 : 0] s00_axi_rresp .s00_axi_rvalid(axi_RVAILD), // output wire s00_axi_rvalid .s00_axi_rready(axi_RREADY), // input wire s00_axi_rready .s00_axi_aclk(axi_aclk), // input wire s00_axi_aclk .s00_axi_aresetn(axi_aresetn) // input wire s00_axi_aresetn ); endmodule
下面这个这个fpga工程的仿真脚本
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2018/05/21 11:10:59 // Design Name: // Module Name: test_tb // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module test_tb(); reg axi_aclk; // AXI总线时钟 reg axi_aresetn; // 系统复位信号 reg r_app_txn; wire w_err; // 状态指示,出现错误 wire w_txn_done; // 状态指示,发送完毕 test_axi u1 ( .axi_aclk(axi_aclk), .axi_aresetn(axi_aresetn), .app_txn(r_app_txn), .state_err(w_err), .state_done(w_txn_done) ); always begin #10; axi_aclk = ~axi_aclk; end initial begin axi_aclk = 1'b0; axi_aresetn = 1'b1; r_app_txn = 1'b1; #10; axi_aresetn = 1'b0; #5; r_app_txn = 1'b0; #5; axi_aresetn = 1'b1; #5; r_app_txn = 1'b1; end endmodule
这个是运行仿真脚本后的master写的波形
这个是运行仿真脚本后master读的波形
对比写和读可以发现写入的和读出的是一致的说明这个master对这个slave进行读写是成功的
对于这个axi协议的各个引脚代表的含义我这里不做一一介绍,下面的截图里面已经说得比较清楚了
我这里主要介绍一个主机master对这个从机slave进行读写的详细过程
master slave
从机采集到主机的地址和数据从机内部开始进行执行写
assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;(从机开始写数据的使能条件)
从机写完成后:
上面介绍的是一个master对slave写的全部过程
这里介绍的是master对slave读
master slave
assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;(进行读时使能条件)
主机读取完成后:
这里最后将这个读写过程总结一下
主机master进行写
主机master进行读
将这个当做笔记来进行记录以免以后自己忘记了