前篇博文我们试验了AXI4-Lite协议读写BRAM,这里我们试验一下完整的AXI4协议。流程跟AXI4-Lite是一样的。省略的部分请参考:编写AXI4-Lite协议读写BRAM并仿真验证
一. 建立工程
略
二. 创建块设计
原理图同AXI4-Lite,不同点在于可以直接拖入三个IP直接连线,AXI BRAM Controller协议选择AXI4。
搭建完成后,需要进行封装。
三. 编写testbench
axiBram_tb.sv,代码如下:
/*
* @Author: Xu XiaoKang
* @Email: xuxiaokang_up@qq.com
* @Date: 2020-08-03 14:40:33
* @LastEditors: xu XiaoKang
* @LastEditTime: 2020-08-04 16:40:00
* @Filename:
* @Description: AXI4 Master
*/
module axi4Bram_tb ();
timeunit 1ns;
timeprecision 1ps;
logic [14:0] M_AXI_awaddr;
logic [7 :0] M_AXI_awlen;
logic [2 :0] M_AXI_awsize;
logic [1 :0] M_AXI_awburst;
logic M_AXI_awlock;
logic [3 :0] M_AXI_awcache;
logic [2 :0] M_AXI_awprot;
logic [3 :0] M_AXI_awqos;
logic M_AXI_awvalid;
logic M_AXI_awready;
logic [31:0] M_AXI_wdata;
logic [3 :0] M_AXI_wstrb;
logic M_AXI_wlast;
logic M_AXI_wvalid;
logic M_AXI_wready;
logic [1:0] M_AXI_bresp;
logic M_AXI_bvalid;
logic M_AXI_bready;
logic [14:0] M_AXI_araddr;
logic [7 :0] M_AXI_arlen;
logic [2 :0] M_AXI_arsize;
logic [1 :0] M_AXI_arburst;
logic M_AXI_arlock;
logic [3 :0] M_AXI_arcache;
logic [2 :0] M_AXI_arprot;
logic [3 :0] M_AXI_arqos;
logic M_AXI_arvalid;
logic M_AXI_arready;
logic [31:0] M_AXI_rdata;
logic [1 :0] M_AXI_rresp;
logic M_AXI_rlast;
logic M_AXI_rvalid;
logic M_AXI_rready;
logic clk;
logic rstn;
// 生成时钟
localparam CLKT = 2;
initial begin
clk = 0;
forever #(CLKT / 2) clk = ~clk;
end
// 初始化一些不变的信号
initial begin
M_AXI_awlock = 1'b0; // Normal access
M_AXI_awcache = 4'b0000; // 指示内存类型
M_AXI_awprot = 3'b000; // 非特权且安全的数据访问
M_AXI_awqos = 4'b0000;
M_AXI_arlock = 1'b0; // Normal access
M_AXI_arcache = 4'b0000; // 指示内存类型
M_AXI_arprot = 3'b000; // 非特权且安全的数据访问
M_AXI_arqos = 4'b0000;
end
initial begin
rstn = 0;
#(CLKT * 5)
rstn = 1;
// 写交易
M_AXI_awaddr = 15'b000_0000_0000_0000; // 写入基地址
M_AXI_awlen = 8'd10; // 实际传输数据量 = awlem + 1
M_AXI_awsize = 3'd2; // 每份数据占2^2=4字节, 默认是数据总线宽度
M_AXI_awburst = 2'b01; // INCR, 增地址模式
M_AXI_awvalid = 1'b1;
wait(M_AXI_awready == 1'b1) #(CLKT * 1) M_AXI_awvalid = 1'b0;
#(CLKT * 10.5)
M_AXI_wdata = 32'd12;
M_AXI_wstrb = 4'b1111;
M_AXI_wlast = 1'b0;
repeat(M_AXI_awlen) begin
M_AXI_wvalid = 1'b1;
wait(M_AXI_wready == 1'b1)
#(CLKT * 1)
M_AXI_wdata = M_AXI_wdata + 1'b1;
end
M_AXI_wlast = 1'b1;
wait(M_AXI_wready == 1'b1)
#(CLKT * 1)
M_AXI_wvalid = 1'b0;
M_AXI_wlast = 1'b0;
M_AXI_bready = 1'b1;
wait(M_AXI_bvalid == 1'b1) #(CLKT * 1) M_AXI_bready = 1'b0;
// 读交易
M_AXI_araddr = M_AXI_awaddr;
M_AXI_arlen = M_AXI_awlen;
M_AXI_arsize = M_AXI_awsize;
M_AXI_arburst = M_AXI_awburst;
M_AXI_arvalid = 1'b1;
wait(M_AXI_arready == 1'b1) #(CLKT * 1) M_AXI_arvalid = 1'b0;
M_AXI_rready = 1'b1;
wait(M_AXI_rlast == 1'b1) #(CLKT * 1) M_AXI_rready = 1'b0;
#(CLKT * 5) $stop;
end
bram_wrapper bram_wrapper_inst_0 (.*);
endmodule
四. 运行仿真
使用vivado 2018.3 和 modelsim 10.6e SE-64 联合仿真。
可见,采用增地址模式,连续写入11个数据,从机能正确返回写响应bresp 和 bvalid,对同一地址的读取,读到的数据同之前写入的数据相同,故AXI4读写BRAM没有问题。
五. 总结与分享
AXI4相较AXI4-Lite支持连续写和连续读,当需要交互的数据量大时,可采用AXI4。另外,如果存储器件支持同时读写,用AXI4进行同时读写也没问题,读写通道是相互独立的。
工程文件:axiRwRam2018.7z。
欢迎大家关注我的公众号:徐晓康的博客,回复以下四位数字获取。
4136
建议复制过去不会码错字!
如果本文对你有所帮助,欢迎点赞、转发、收藏、评论让更多人看到,赞赏支持就更好了。
如果对文章内容有疑问,请务必清楚描述问题,留言评论或私信告知我,我看到会回复。
徐晓康的博客持续分享高质量硬件、FPGA与嵌入式知识,软件,工具等内容,欢迎大家关注。