AXI FULL采用READY,VALID 握手通信机制,可支持最大256长度的突发传输,详细内容可参考博客
下面是AXI突发传输读和写的时序图。
读时序:

写时序:

在AXI协议中,数据传输发生在VALID和 READY信号同时为高的时候,如下图所示:

根据这三张图,我们就能编写代码进行测试。
verilog代码(主机)

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/03/08 15:26:05
// Design Name:
// Module Name: PL_DDR_Test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
///*
本程序功能为:从start_addr地址开始处连续读取32个数据至buffer,然后分别将其加1,写回原地址处
*/module PL_DDR_Test(
//全局信号
input logic ACLK,
input logic ARESETn,
//写地址通道信号
output logic AWVALID,
output logic [31:0]AWADDR,
output logic [7:0]AWLEN,
output logic AWID,              //dont care
output logic [2:0]AWSIZE,       //dont care
output logic [1:0]AWBURST,      //dont care
output logic AWLOCK,            //dont care
output logic [3:0]AWCACHE,      //dont care
output logic [2:0]AWPROT,       //dont care
output logic [3:0]AWQOS,        //dont care
output logic AWUSER,            //dont care
input logic AWREADY,
//写数据通道信号
output logic [63:0]WDATA,
output logic [7:0]WSTRB,
output logic WLAST,
output logic WUSER,             //dont care
output logic WVALID,
input logic WREADY,
//写应答通道信号
output logic BREADY,
input logic BID,                //dont care
input logic [1:0]BRESP,
input logic BUSER,              //dont care
input logic BVALID,
//读地址通道信号
output logic ARID,              //dont care
output logic [31:0]ARADDR,
output logic [7:0]ARLEN,
output logic [2:0]ARSIZE,       //dont care
output logic [1:0]ARBURST,      //dont care
output logic [1:0]ARLOCK,       //dont care
output logic [3:0]ARCACHE,      //dont care
output logic [2:0]ARPROT,       //dont care
output logic [3:0]ARQOS,        //dont care
output logic ARUSER,            //done care
output logic ARVALID,
input logic ARREADY,
//读数据通道
output logic RREADY,
input logic RID,                //dont care
input logic [63:0]RDATA,
input logic [1:0]RRESP,         //dont care
input logic RLAST,
input logic RUSER,              //dont care
input logic RVALID);assign AWID = 1'b0;
assign AWSIZE  = 3'b011;
assign AWBURST = 2'b01;
assign AWLOCK  = 1'b0;
assign AWCACHE = 4'b0011;
assign AWPROT = 3'b000;
assign AWQOS = 4'b0000;
assign AWUSER = 1'b1;
assign WUSER = 1'b1;assign ARID = 1'b0;
assign ARSIZE = 3'b011;
assign ARBURST = 2'b01;
assign ARLOCK = 1'b0;
assign ARCACHE = 4'b0011;
assign ARPROT = 3'b000;
assign ARQOS = 4'b0000;
assign ARUSER = 1'b1;logic [9:0]wr_cnt;
logic [9:0]rd_cnt;
logic rd_done;
logic wr_done;
logic read_start;
logic write_start;
logic test_start;
logic test_done;
//
logic [31:0]start_addr;
logic [9:0] test_len;            //=31,即突发传输长度32
logic [63:0] data_buffer [0:31];enum {IDLE,READ,WRITE,DONE} State,NextState;
//*************************************************************************//
//test_len
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)test_len<=31;
//test_start
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)test_start<=1;
elsetest_start<=0;
//start_addr
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)start_addr<=0;
//FSM
always_ff@(posedge ACLK,negedge ARESETn)
beginif(!ARESETn)State<=IDLE;elseState<=NextState;
end
//FSM
always@(*)
case(State)IDLE:if(test_start)NextState=READ;elseNextState=IDLE;READ:if(rd_done)NextState=WRITE;elseNextState=READ;WRITE:if(wr_done)NextState=DONE;elseNextState=WRITE;DONE:NextState=DONE;default:NextState=IDLE;
endcase
//读地址通道
always_combread_start=test_start;
//ARVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)ARVALID<=1'b0;
else if(NextState==READ&&read_start)                      //read_start为一个宽一个周期的脉冲ARVALID<=1'b1;
else if(ARVALID==1'b1&&ARREADY==1'b1)                     //读通道数据传输完成ARVALID<=1'b0;
//ARADDR
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)ARADDR<=32'd0;
else if(NextState==READ&&read_start)ARADDR<=start_addr;
//ARLEN
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)ARLEN<=8'd0;
else if(NextState==READ&&read_start)ARLEN<=test_len;
//读数据通道
//rd_cnt
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)rd_cnt<=10'd0;
else if(RVALID&&RREADY)      //完成一个数据的读取,计数器加1if(RLAST)rd_cnt<=0;elserd_cnt<=rd_cnt+1'b1;
//data_buffer
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)for(int i=0;i<32;i++)data_buffer[i]<=32'd0;
else if(RVALID&&RREADY)data_buffer[rd_cnt]<=RDATA;
//RREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)RREADY<=0;
else if(RVALID&&~RREADY)RREADY<=1;
else if(RVALID&&RREADY&&RLAST)                       //最后一个数据读取完成RREADY<=0;
//rd_done
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)rd_done<=0;
else if(RLAST)rd_done<=1;
else rd_done<=0;
//写地址通道
//write_start
always_comb
beginwrite_start=rd_done;
end
//AWVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)AWVALID<=0;
else if(NextState==WRITE&&write_start)AWVALID<=1;
else if(AWVALID&&AWREADY)                         //写地址通道传输完成AWVALID<=0;
//AWADDR
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)AWADDR<=32'd0;
else if(NextState==WRITE&&write_start)AWADDR<=start_addr;
//AWLEN
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)AWLEN<=8'd0;
else if(NextState==WRITE&&write_start)AWLEN<=test_len;                                      //写突发传输长度为32
//写数据通道
//wr_cnt
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)wr_cnt<=10'd0;
else if(WVALID&&WREADY)                         //完成一个数据的写入,计数器加1if(WLAST)wr_cnt<=0;elsewr_cnt<=wr_cnt+1;
//WVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)WVALID<=0;
else if(AWVALID&&AWREADY)                      //写地址通道传输完成,开始写数据WVALID<=1;
else if(WLAST&&WVALID&&WREADY)                 //最后一个数据传输完成WVALID<=0;
//WSTRB
always_ff@(posedge ACLK,negedge ARESETn)                  //
if(!ARESETn)WSTRB<=8'd0;
else if(AWVALID&&AWREADY)                WSTRB<=8'hff;
//WDATA
always_comb
beginif(WVALID&&WREADY)                                  //此时写入数据有效WDATA=data_buffer[wr_cnt]+1;    elseWDATA=0;
end
//WLAST
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)WLAST<=0;
else if(wr_cnt==test_len-1&&WVALID&&WREADY)                           //31-1=30WLAST<=1;
else WLAST<=0;
//写响应通道
//BREAY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)BREADY<=0;
else if(AWVALID&&AWREADY)BREADY<=1;
else if(BVALID&&BRESP==2'b00)                      //BRESP=OKEYBREADY<=0;
//wr_done
always_comb
beginif(BREADY&&BVALID&&BRESP==2'b00)wr_done=1;elsewr_done=0;
end
//test_done
always_combtest_done=wr_done;endmodule

Testbench(从机)

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/03/08 18:32:44
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module test;
//全局信号
logic ACLK;
logic ARESETn;
//写地址通道
logic AWVALID;
logic [31:0]AWADDR;
logic [7:0]AWLEN;                  //突发传输长度,实际长度为AWLEN+1
logic AWREADY;
//写数据通道
logic [63:0] WDATA;
logic WVALID;
logic [7:0] WSTRB;                //dont care
logic WLAST;
logic WREADY;
//写响应通道
logic BVALID;
logic BREADY;
logic [1:0]BRESP;
//读数据通道
logic [63:0]RDATA;
logic RVALID;
logic RREADY;
logic RLAST;
//读地址通道
logic [31:0] ARADDR;
logic [7:0] ARLEN;
logic ARVALID;
logic ARREADY;
//MEM
logic [63:0] mem [0:31];
//other signal
logic [31:0] rd_base_addr;
logic [31:0] wr_base_addr;
logic [9:0] rd_len;
logic [9:0] wr_len;
logic [9:0] rd_cnt;                     //这里的rd是相对与主机来说的,即主机读取,从机发送
logic [9:0] wr_cnt;
//initialize memory
/*initial beginfor(int i=0;i<32;i++)mem[i]=i;
end*/
//ACLK,ARESET
initial beginACLK=0;forever begin#5 ACLK=~ACLK;end
end
initial beginARESETn=0;#10ARESETn=1;
end
//处理主机发起的读请求
//读地址通道
//ARREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)ARREADY<=0;
else if(ARVALID&&~ARREADY)                    //ARVALID信号为1,拉高ARREADY以接受信息ARREADY<=1;
else if(ARVALID&&ARREADY)                     //读地址通道数据接受完毕ARREADY<=0;
//rd_base_addr
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)rd_base_addr<=32'd0;
else if(ARREADY&&ARVALID)rd_base_addr<=ARADDR;
//rd_len
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)rd_len<=0;
else if(ARVALID&&ARREADY)rd_len<=ARLEN;
//读数据通道
//rd_cnt
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)rd_cnt<=0;
else if(RVALID&&RREADY)                  //从机发送一个数据完成if(RLAST)                            //所有数据发送完毕rd_cnt<=0;else                                 //计数器加1rd_cnt<=rd_cnt+1;
//RVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)RVALID<=0;
else if(ARREADY&&ARVALID)                    //读地址通道结束,读数据通道开始RVALID<=1;
else if(RVALID&&RREADY&&RLAST)               //最后一个数据发送完成RVALID<=0;
//RDATA
always_comb                                  //组合逻辑,否则数据相对于发送次数延迟了一个周期
begin
if(RVALID&&RREADY)RDATA=mem[rd_cnt];
elseRDATA=0;
end
//RLAST
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)RLAST<=0;
else if(rd_cnt==rd_len-1&&RVALID&&RREADY)              //rd_len等于实际长度-1RLAST<=1;
elseRLAST<=0;
//处理主机发起的写请求
//写地址通道
//AWREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)AWREADY<=0;
else if(AWVALID&&~AWREADY)AWREADY<=1;
else if(AWVALID&&AWREADY)                   //写地址通道接收信息完毕AWREADY<=0;
//wr_len
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)wr_len<=0;
else if(AWVALID&&AWREADY)wr_len<=AWLEN;
//wr_base_addr
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)wr_base_addr<=0;
else if(AWVALID&&AWREADY)wr_base_addr<=AWADDR;
//写数据通道
//WREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)WREADY<=0;
else if(AWVALID&&AWREADY)                  //写地址通道完成之后拉高WREADY以等待数据的到来WREADY<=1;
else if(WVALID&&WLAST&&WREADY)             //最后一个数据接收后拉低WREADYWREADY<=0;
//wr_cnt                                  //wr是相对于主机来说的,主机写数据,从机接收数据
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)wr_cnt<=0;
else if(WVALID&&WREADY)if(WLAST)                            //从机接受数据完成wr_cnt<=0;else wr_cnt<=wr_cnt+1;
//WDATA
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
beginfor(int i=0;i<32;i++)mem[i]<=i;
end
else if(WVALID&&WREADY)mem[wr_cnt]<=WDATA;
//写响应通道
//BVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)BVALID<=0;
else if(WVALID&&WLAST&&WREADY)BVALID<=1;
else if(BVALID&&BREADY&&BRESP==2'b00)BVALID<=0;
//BRESP
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)BRESP<=2'b11;
else if(WVALID&&WREADY&&WLAST)BRESP<=2'b00;
else if(BREADY&&BVALID&&BRESP==2'b00)BRESP<=2'b11;
//打印结果
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn);
else if(BREADY&&BVALID&&BRESP==2'b00)
beginfor(int i=0;i<32;i++)$display("%d",mem[i]);
end
//例化主机
PL_DDR_Test U(
//全局信号
.ACLK(ACLK),
.ARESETn(ARESETn),
//写地址通道信号
.AWVALID(AWVALID),
.AWADDR(AWADDR),
.AWLEN(AWLEN),
.AWID(),              //dont care
.AWSIZE(),       //dont care
.AWBURST(),      //dont care
.AWLOCK(),            //dont care
.AWCACHE(),      //dont care
.AWPROT(),       //dont care
.AWQOS(),        //dont care
.AWUSER(),            //dont care
.AWREADY(AWREADY),
//写数据通道信号
.WDATA(WDATA),
.WSTRB(WSTRB),
.WLAST(WLAST),
.WUSER(),             //dont care
.WVALID(WVALID),
.WREADY(WREADY),
//写应答通道信号
.BREADY(BREADY),
.BID(),                //dont care
.BRESP(BRESP),
.BUSER(),              //dont care
.BVALID(BVALID),
//读地址通道信号
.ARID(),              //dont care
.ARADDR(ARADDR),
.ARLEN(ARLEN),
.ARSIZE(),       //dont care
.ARBURST(),      //dont care
.ARLOCK(),       //dont care
.ARCACHE(),      //dont care
.ARPROT(),       //dont care
.ARQOS(),        //dont care
.ARUSER(),            //done care
.ARVALID(ARVALID),
.ARREADY(ARREADY),
//读数据通道
.RREADY(RREADY),
.RID(),                //dont care
.RDATA(RDATA),
.RRESP(RRESP),         //dont care
.RLAST(RLAST),
.RUSER(),              //dont care
.RVALID(RVALID)
);
endmodule

代码完成的功能为:主机从从机的0地址起始地址处连续读取32个64位数据,然后分别加1,再通过突发写将结果写回至原先的地方。
代码已通过仿真测试。

AXI FULL协议学习与仿真相关推荐

  1. AXI 总线协议学习笔记(4)

    引言 前面两篇博文从简单介绍的角度说明了 AXI协议规范. AXI 总线协议学习笔记(2) AXI 总线协议学习笔记(3) 从本篇开始,详细翻译并学习AXI协议的官方发布规范. 文档中的时序图说明: ...

  2. AXI接口协议学习总结

    AXI接口协议学习总结 下面将AXI接口协议学到的相关内容整理如下 一.AXI接口协议定义 AXI是Advanced eXtensible Interface的缩写,译为高级可扩展接口协议,是ARM公 ...

  3. AXI 总线协议学习笔记(3)

    引言 上篇文章主要介绍了 AMBA以及AXI协议的基本内容,本文接续前文,继续介绍AXI协议的 原子访问.传输行为和事务顺序等. AXI 总线协议学习笔记(2)https://blog.csdn.ne ...

  4. AXI 总线协议学习笔记(2)

    引言 从本文开始,正式系统性学学习AXI总线. 如何获取官方协议标准? 第一步:登陆官网:armDeveloper 第二步:登录,无账号需要注册 第三步:点击文档 第四步: 第五步:浏览页面建议下载下 ...

  5. AXI协议学习笔记~~

    AXI总线简介 ​  AXI属于AMBA(The ARM Advanced Microcontroller Bus Architecture)家族的一员,AXI协议在AMBA3.0版本中开始出现,并在 ...

  6. 片上总线协议学习(1)——SiFive的TileLink与ARM系列总线的概述与对比

    link 片上总线协议学习(1)--SiFive的TileLink与ARM系列总线的概述与对比 finally 27 人赞同了该文章 一.背景介绍 随着超大规模集成电路的迅速发展,半导体工业进入深亚微 ...

  7. 网络协议分析与仿真课程设计报告:网络流量分析与协议模拟

    公众号:CS阿吉 网络协议分析与仿真课程设计报告  题  目:网络流量分析与协议模拟 专业名称:         网络工程 班    级: 学生姓名:           阿吉 学号(8位): 指导教 ...

  8. matlab仿真参考文献,量子通信论文,关于BB84协议其MATLAB仿真相关参考文献资料-免费论文范文...

    导读:此文是一篇量子通信论文范文,为你的毕业论文写作提供有价值的参考. (厦门警备区 福建厦门 361003) 摘 要:量子通信是通信领域研究的热点和前沿.论文范文的通信工程人员和在校学生应着手学习量 ...

  9. 有限理性建模的方法和计算机平台,有限理性假设下的多方计算协议建模与仿真...

    有限理性假设下的多方计算协议建模与仿真 始于2004年的理性多方计算(Rational Multiparty Computation,RMPC)是密码学的新兴研究方向,在多方隐私保护合作计算.电子商务 ...

  10. AODV协议的NS2仿真

    无线传感网技术团队科研原始记录 姓名:赵亮 时间:2017.12.30 周次:18 记录编号:3 科研方向: 无线传感网 原始记录       本周继续在NS2下进行仿真工作. 1. Trace文件格 ...

最新文章

  1. Nmap扫描教程之基础扫描详解
  2. h5如何动态获取键盘高度_动态获取键盘高度
  3. c 全局变量多线程调用_c语言局部变量 静态局部变量 全局变量与静态全局变量...
  4. SSM实现个人博客-day03
  5. IoT与区块链的机遇与挑战
  6. 计算机c盘能分区吗,电脑C盘怎么分区
  7. fibonacci数列的题目——剑指Offer
  8. 李开复:人工智能行业发展与投资趋势
  9. 初使用 ReportViewer 控件时遇到的一点小麻烦
  10. 马斯克:正在认真考虑建立社交媒体平台
  11. vscode 智能提示失效
  12. 21个以Bootstrap为框架的WordPress免费主题模板下载
  13. 关于IplImage中widthstep的大小与width,nchannels等的关系的问题_widthstep
  14. 怎么更改win7登录界面 梦幻桌面动态效果电脑桌面快速分屏设置虚拟wifi热点方法_桌面图标弹出提示飞雪桌面日历自定义桌面
  15. 小米浏览器 解析html5,JavaScript - 判断当前用户使用的浏览器
  16. 计算机网络常用通讯方式,通信方式
  17. 现在,让客服接管数字化企业
  18. ROC和 区别p值和q值
  19. 橙瓜码字多端同步、十份云储存本地实时备份,最放心的码字软件
  20. 【批处理DOS-CMD命令-汇总和小结】-磁盘管理和修复、磁盘和分区属性的管理、设置隐藏分区卷(convert、diskpart、chkdsk)

热门文章

  1. 校验和checksum、哈希值是什么?
  2. .NET利用ActionFilter特性记录日志或者运行性能计数器。(log trace or perform perfcounter by actionFilter attribute)...
  3. 笔记本电脑里计算机未响应,浅析笔记本win7系统下Word程序总是未响应的原因及解决办法【图文】...
  4. 【英语:基础进阶_原著扩展阅读】J1.英文原著的选择和有效阅读方法
  5. Win10声卡驱动正常但没声音怎么办?驱动人生解决办法
  6. SlidingBall滚动效果集成问题解决经验
  7. 2021最新调查报告来了!揭露中国程序员工作和生活真实现状
  8. Android事件分发机制
  9. 【javascript】解析psd文件踩坑
  10. 搭建STM32开发环境