前言
开博的目的很简单,一来每天花点做个总结,感觉自己能顺畅的讲清楚了,也就算真的消化了,二来希望能通过坚持写点东西,提高一下老师眼里“意识流”的文风,总是有好处的。刚好前期师兄建议学习下AXI接口,这样以后遇到没用过的IP核,只要它支持AXI协议,拿来就能用,本着懒人图方便的原则,对AXI协议简单进行了研究,本人技术和叙述水平有限,有问题的地方欢迎大家指正。
一、AXI协议简介
AXI全称Advanced eXtensible Interface,主要描述主设备和从设备之间的数据传输方式,具有高性能、高带宽、低延时的特点。目前常见的AXI4.0是AXI协议的第二个版本,包含于2010年发布的AMBA4.0中。
AXI4.0协议包含AXI4.0、AXI-lite、AXI-stream三种接口标准。本文以AXI-bram IP核为例,介绍AXI4.0接口的使用
二、特点及关键信号描述
AXI协议采用控制与数据传输分离的方式,基于突发定义了5个独立的通道:写地址通道、写数据通道、写响应通道、读地址通道、读数据通道。每一条通道上都有一对用于实现双向握手机制的ready和valid信号。其中,valid信号由源端发出,表示此时通道上是否有数据、命令等信息;ready由目的端发出,表示此时目的端是否可以接收数据。这里的源端目的端和AXI协议的主从端不同,同一连线结构中的主从端通常固定,从端通常为调用的ip核或其他外设,源端目的端则根据数据传输方向的不同,随时发生变化。
valid、ready:用于实现双向握手机制,仅当valid和ready信号均为高电平时,传输的数据有效。例如在写通道中,主端检测到从端ready信号为高时,表示从端可以接受写命令,此时主端将valid信号拉高并保持一个时钟周期,为发出一个写命令。
写地址通道:信号以AW为开头,该通道用于主端向从端发起写命令,并规定写入地址、突发的大小、长度、类型等信息。信号包括s_axi_awaddr、s_axi_awburst、s_axi_awcache、s_axi_awlen、s_axi_awlock、s_axi_awprot、s_axi_awready、s_axi_awsize、s_axi_awvalid。
s_axi_awaddr:起始写入地址,随写命令一同发出,固定了本次写入数据的起始存储地址。AXI协议采用字节寻址,例如一组32位的数据,写入后,则会占用4个地址。(测试的时候没注意,被小坑了一把)
s_axi_awlen:AXI中数据以突发的形式传输,每个突发分为多个transfer,该信号决定了本次突发中transfer的个数,可以理解为该突发中数据的组数,例如s_axi_awlen为1时,表示该突发中包含两组数据。
s_axi_awsize:该信号规定了突发中数据的位宽,但位宽的设置不能超过总线位宽(可以简单理解为不能超过调用的ram的位宽)。如下表所示:
s_axi_awsize | 位宽(字节) |
3'b000 | 1 |
3'b001 | 2 |
3'b010 | 4 |
3'b011 | 8 |
3'b100 | 16 |
3'b101 | 32 |
3'b110 | 64 |
3'b111 | 128 |
s_axi_awburst:该信号规定了突发的三种传输类型:fixed、incr、wrap。如下图所示:
awburst | type |
2'b00 | fixed |
2'b01 | incr |
2'b10 | wrap |
2'b11 | reversed |
fixed:该类型中,burst中的所有数据都将使用初始地址,该类型适合对某一地址进行多次数据更新。
incr:该类型中,burst中的后续数据的存储地址会在初始地址的基础上进行递增,递增幅度与传输宽度相同,常用于ram等通过地址映射的存储器进行数据读写。
wrap:该类型中,burst中的数据首先根据起始地址得到绕回边界地址(wrap boundary)与最高地址。当前地址小于最高地址时,WRAP 与 INCR 类型完全相同,地址递增。但到递增后的地址到达最高地址后,地址直接回到绕回边界地址,再进行递增,就这样循环往复。
s_axi_awburst、s_axi_awlen、s_axi_awsize:这三个信号一起,规定了数据写入时的位宽、长度以及存储形式,同时要注意的是,一次突发的地址范围不能超过4KB(为什么?不知道,没有具体去了解)。
写数据通道:信号以W开头,该通道用于主端往从端写入数据、选通信号等信息,信号包括s_axi_wdata、s_axi_wlast、s_axi_wready、s_axi_wstrb、s_axi_wvalid。
s_axi_wdata:传输写入数据。
s_axi_wstrb:在突发位宽与总线位宽不同时,使用该信号指示写入数据中的有效字节,当二者位宽相同时,该信号全部拉高即可。
s_axi_wlast:指示本次突发传输的最后一组数据。
写响应通道:信号以B开头,该通道用于主端完成对从端的数据写入后,从端发给主端的反馈信息,信号包括:s_axi_bready、s_axi_bresp、s_axi_bvalid。
s_axi_bresp:该信号由目的端反馈数据写入情况,源端根据该信号判断数据是否写入成功。(一般都是成功的,无视就好了,大不了丢包),如下表所示:
resp | 反馈情况 |
2‘b00 | OKAY/常规访问成功 |
2‘b01 | EXOKEY/独占访问成功 |
2‘b10 | SLVERR/从端错误 |
2‘b11 | DECERR/解码错误 |
读地址通道:信号以AR开头,该通道用于主端向从端发起读命令,并规定读出地址、突发的大小、长度等信息,信号包括s_axi_araddr、s_axi_arburst、s_axi_arcache、s_axi_arlen、s_axi_arlock、s_axi_arprot、s_axi_arready、s_axi_arsize、s_axi_arvalid。
读数据通道:信号以R开头,该通道用于从端向主端发送读出的数据,并在数据全部读出后,发出反馈信息,信号包括s_axi_rdata、s_axi_rlast、s_axi_rready、s_axi_rvalid。
读地址通道、读数据通道的关键信号与写操作的关键信号使用方式相同,不再重复说明。这里要注意的是,读操作将读反馈信号放入了读数据通道中,没有单独的读响应通道。
除了上面介绍到的数据之外,AXI4接口还包括cache、user等信号线,看手册上讲,应该是可以实现些更多的功能,但是对于大部分我这样的同志来讲,应该是用不上了,悬空放那儿就行了,不用管他。
三、仿真
IP核调用
此次测试调用的是xlinx的AXI BRAM Controller,位宽设置为32位,如下图所示:
仿真代码测试了连续写10组数据,分10次读出,以及分10次写入10组数据,连续读出两种情况,并将写响应信号保持为1。
连续写,分开读:
从图中可以看到,写命令规定了起始存储地址为0,写入突发分10个transfer写入,数据位宽为32,读出时,从地址0开始读,读出数据位宽为32,每读一次,地址加4,分十次读取写入的数据。
分开写,连续读:
结语
axi4-lite是简化版的axi4,只支持单次写入数据,axi-stream则取消了地址通道,是一个单纯数据传输接口。总的来讲,水平有限,第一篇文就这个样子了,有不当之处欢迎指正。
---------------分割线---------------
关于axi4-lite,和axi4接口有一个小区别,单独开一章又没必要,补充说明一下,与axi4接口先处理读写命令(地址通道),再处理读写数据(数据通道)不同,axi4-lite需同时发送命令(地址)和数据,例如写入数据时,只有当awvalid和wvalid同时为高电平时,表示写命令有效,此时从端将数据写入地址指向的存储区,并给出反馈。