我这里一共调用了两个自定义的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进行读
将这个当做笔记来进行记录以免以后自己忘记了