赞
踩
AXI是ARM 1996年提出的微控制器总线家族AMBA中的一部分。AXI的第一个版本出现在AMBA3.0,发布于2003年。当前的最新的版本发布于2010年。AXI 4总线和别的总线一样,都用来传输bits信息 (包含了数据或者地址) 。AXI4总线有三种类型,分别是AXI4、AXI4-Lite、AXI4-Stream
AXI4:主要面向高性能地址映射通信的需求,支持突发传输;
AXI4-Lite:是一个简单地吞吐量地址映射性通信总线,不支持突发传输;
AXI4-Stream:不包含地址,面向高速流数据传输;
AXI4 是一种高性能memory-mapped总线,分为主、从两端,两者间可以连续的进行通信。AXI4及AXI4Lite有地址,AX14能够实现burst传输,可以在一个地址后传输多个数据,最多可以达256 字节。AXI4-Lite不支持burst传输。AXI4-Stream 只有一个通道,不需要地址,可以burst 传输无限的数据。假设有master A,和 slave B,A与B通过AXI4或者AXI4Lite连接通讯,A可以把B这个外设看作A上的某个地址。当A向B传输数据时,就等同于A向这个地址传数。
AXI4 和 AXI4-Lite接口包含5个不同的通道:两个读通道和三个写通道。
两个读通道:读地址通道(read addresschannel)、读数据通道(read data channel):
三个写通道: 写地址通道(write addresschannel)、写数据通道(write data channel)、写响应通道(write response channel);
相比于 AXI4,AXI4-Stream 不涉及地址。AXI4-Stream传输的数据流包含三种类型: data type、position type、 null type 。data type是最有意义的数据; position type作为占位符使用,可以用来表征date type 的相对位置,null type不包含任何有用的信息。
数据流的结构可以有很多种,例如: 可以只传数据,也即都是data type,不包含position type和null type; 也可以将data type 和 null type 混着传输;还可以将position type 和 data type混着传输。当然,三者混着传输也没有问题。
AXI与AXI-lite信号描述如下所示,由于AXI-lite不支持突发,所以与突发相关的管教都不具备。
//全局信号 .M_AXI_ACLK(m00_axi_aclk),//时钟 .M_AXI_ARESETN(m00_axi_aresetn),//全局复位 //写地址通道信号 .M_AXI_AWID(m00_axi_awid),//AXI4-LITE不支持 写地址ID。这个信号用于写地址信号组的标记,用来标识数据传输顺序。详见协议定义。 .M_AXI_AWADDR(m00_axi_awaddr),//写地址。写地址给出突发数据传输的第一个传输地址。 .M_AXI_AWLEN(m00_axi_awlen),//AXI4-LITE不支持 突发长度。给出突发传输中准确的传输个数。支持INCR和WRAP传输模式。(长度)突发长度=awlen+1 .M_AXI_AWSIZE(m00_axi_awsize),//AXI4-LITE不支持 突发大小。这个信号用于确定突发传输中每个传输的大小。(宽度)总线位宽=2^size Betyes .M_AXI_AWBURST(m00_axi_awburst),//AXI4-LITE不支持 突发类型。该信息与突发大小信息一起,表示在突发过程中,地址如何应用于每个传输。支持INCR和WRAP传输模式。 .M_AXI_AWLOCK(m00_axi_awlock),//AXI4-LITE不支持 锁类型。该信号提供了关于传输原子特性的额外信息(普通或互斥访问)。AXI3支持,AXI4不支持 .M_AXI_AWCACHE(m00_axi_awcache),//缓存类型,建议值为0011。 .M_AXI_AWPROT(m00_axi_awprot),//保护类型,访问权限,建议值为000。 .M_AXI_AWQOS(m00_axi_awqos),//QoS标识符,xilinx AXI4不支持 .M_AXI_AWUSER(m00_axi_awuser),//xilinx AXI4不支持 .M_AXI_AWVALID(m00_axi_awvalid),//写地址有效信号。为高指示地址有效。 .M_AXI_AWREADY(m00_axi_awready),//写地址准备信号。为高表示从设备空闲,准备接收地址;为低表示从设备忙。 //写数据通道信号 .M_AXI_WDATA(m00_axi_wdata),//写数据,AXI-LITE仅支持32bit,AXI支持32bit-1024bit .M_AXI_WSTRB(m00_axi_wstrb),//写字节选通,用于表示更新存储器的字节通道,对于数据总线的每8位数据有一位写选通信号 .M_AXI_WLAST(m00_axi_wlast),//AXI-LITE不支持 写最后一个数据指示信号。表示突发传输中的最后一个数据。 .M_AXI_WUSER(m00_axi_wuser),//xilinx AXI4不支持。 .M_AXI_WVALID(m00_axi_wvalid),//写有效。为高指示数据有效。 .M_AXI_WREADY(m00_axi_wready),//写准备。为高表示从设备空闲,准备接收数据;为低表示从设备忙。 //写响应通道 .M_AXI_BID(m00_axi_bid),//AXI-LITE不支持 响应ID。写响应识别标记,BID值必须匹配AWID值。 .M_AXI_BRESP(m00_axi_bresp),//写响应。该信号表示写状态,0时候表示没有错误, .M_AXI_BUSER(m00_axi_buser),//xilinx AXI4不支持。 .M_AXI_BVALID(m00_axi_bvalid),//写响应有效。为高指示响应数据有效 .M_AXI_BREADY(m00_axi_bready),//写响应准备。为高表示主设备空闲,准备接收写响应;为低表示主设备忙。 //读地址通道 .M_AXI_ARID(m00_axi_arid),//AXI-LITE不支持 读地址ID。这个信号用于读地址信号组的标记。 .M_AXI_ARADDR(m00_axi_araddr),//读地址。读地址给出突发数据传输的第一个传输地址。 .M_AXI_ARLEN(m00_axi_arlen),//AXI-LITE不支持 突发长度。给出突发传输中准确的传输个数。支持INCR和WRAP传输模式。 .M_AXI_ARSIZE(m00_axi_arsize),//AXI-LITE不支持 突发大小。这个信号用于确定突发传输中每个传输的大小。 .M_AXI_ARBURST(m00_axi_arburst),//AXI-LITE不支持 突发类型。该信息与突发大小信息一起,表示在突发过程中,地址如何应用于每个传输。支持INCR和WRAP传输模式 .M_AXI_ARLOCK(m00_axi_arlock),//锁类型。该信号提供了关于传输原子特性的额外信息(普通或互斥访问) .M_AXI_ARCACHE(m00_axi_arcache),//缓存类型,建议值为0011。 .M_AXI_ARPROT(m00_axi_arprot),//保护类型,建议值为000。 .M_AXI_ARQOS(m00_axi_arqos),//QoS标识符,xilinx AXI4不支持。 .M_AXI_ARUSER(m00_axi_aruser),//xilinx AXI4不支持 .M_AXI_ARVALID(m00_axi_arvalid),// 读地址有效信号。为高指示地址有效 .M_AXI_ARREADY(m00_axi_arready),//读地址准备信号。为高表示从设备空闲,准备接收地址;为低表示从设备忙 //读数据通道 .M_AXI_RID(m00_axi_rid),//AXI-LITE不支持 读ID标记,该信号是读数据信号组标记,由从设备产生RID,RID必须和读交易中的ARID匹配 .M_AXI_RDATA(m00_axi_rdata),//读数据。32位到1024位宽 AXI-LITE只支持32位宽 .M_AXI_RRESP(m00_axi_rresp),//读响应。该信号表示读状态,可允许相应的表示为 .M_AXI_RLAST(m00_axi_rlast),//AXI-LITE不支持 读最后一个数据指示信号。表示突发传输中的最后一个数据 .M_AXI_RUSER(m00_axi_ruser),//xilinx AXI4不支持。 .M_AXI_RVALID(m00_axi_rvalid),//读有效。为高指示数据有效 .M_AXI_RREADY(m00_axi_rready)//读准备。为高表示主设备空闲,准备接收数据;为低表示主设备忙。
AXI-stream信号描述如下所示,
.M_AXIS_ACLK(m00_axis_aclk),//时钟
.M_AXIS_ARESETN(m00_axis_aresetn),//复位
.M_AXIS_TVALID(m00_axis_tvalid),//Stream读写数据有效。为高指示数据有效。
.M_AXIS_TDATA(m00_axis_tdata),//Stream读写数据,8到4096位宽。
.M_AXIS_TSTRB(m00_axis_tstrb),//字节选通信号。用于表示更新存储器的字节通道,对于数据总线的每8位数据有一位选通信号。
.M_AXIS_TLAST(m00_axis_tlast),//表明包的边界,1代表最后数据
.M_AXIS_TREADY(m00_axis_tready)//Stream读写读准备。为高表示对端设备空闲,准备接收数据;为低表示对端设备忙。
AXI4协议主从设备间的读操作使用独立的读地址和读数据通道,只需要一个地址就可以执行最大为256的突发长度的读操作。
读时序如下所示。
(1)首先Master判断arready的信号是否为高电平,若该信号为高电平时,代表slave已经准备好接收新的地址信息,否则Master不能给Slave发送地址信息。
(2)当判断完成后,Master给Slave发送地址信息,即发送araddr;在进行地址发送时,arvalid为高电平,arvalid为高电平,发送araddr。
(3)当地址发送结束之后,slave就会通过read_data通道返回数据,master必须在rready和rvalid信号同时为高时,将数据读取,否则不能读取数据;当最后一个数据发送时,slave会将rlast信号同时拉高,代表最后一个数据发送完成。
写时序如下所示。
AXI写事务是在3个写通道上完成多次数据传输(transfers)
(1)MASTER将写地址及相应的控制信息通过写地址通道发送给SLAVE
(2)MASTER将需要写入该地址的数据通过写输入通道发送给SLAVE
(3)SLAVE将写结果通过写反馈通道发送给MASTER,表明写入是否成功
读事务握手信号的关系:
单箭头指向 可以在前一个信号(本信号)断言之前或之后断言的信号(指向的信号)。
双箭头指向 只有在前一个信号(本信号)断言之后才可以断言的信号(指向的信号)。
所以slave 在断言读取的数据有效信号RVALID之前,必须等到ARVALID与ARREADY断言后。
//---------------------------- //Read Address Channel //---------------------------- always @(posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) begin axi_arvalid <= 1'b0; end // If previously not valid , start next transaction else if (~axi_arvalid && start_single_burst_read) begin axi_arvalid <= 1'b1; end else if (M_AXI_ARREADY && axi_arvalid) begin axi_arvalid <= 1'b0; end else axi_arvalid <= axi_arvalid; end // Next address after ARREADY indicates previous address acceptance always @(posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) begin axi_araddr <= 'b0; end else if (M_AXI_ARREADY && axi_arvalid) begin axi_araddr <= axi_araddr + burst_size_bytes; end else axi_araddr <= axi_araddr; end //-------------------------------- //Read Data (and Response) Channel //-------------------------------- // Forward movement occurs when the channel is valid and ready assign rnext = M_AXI_RVALID && axi_rready; // Burst length counter. Uses extra counter register bit to indicate // terminal count to reduce decode logic always @(posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 || start_single_burst_read) begin read_index <= 0; end else if (rnext && (read_index != C_M_AXI_BURST_LEN-1)) begin read_index <= read_index + 1; end else read_index <= read_index; end always @(posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) begin axi_rready <= 1'b0; end // accept/acknowledge rdata/rresp with axi_rready by the master // when M_AXI_RVALID is asserted by slave else if (M_AXI_RVALID) begin if (M_AXI_RLAST && axi_rready) begin axi_rready <= 1'b0; end else begin axi_rready <= 1'b1; end end // retain the previous value end
写事务握手信号的关系:
单箭头指向 可以在前一个信号(本信号)断言之前或之后断言的信号(指向的信号)。
双箭头指向 只有在前一个信号(本信号)断言之后才可以断言的信号(指向的信号)。
//-------------------- //Write Data Channel //-------------------- assign wnext = M_AXI_WREADY & axi_wvalid; // WVALID logic, similar to the axi_awvalid always block above always @(posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) begin axi_wvalid <= 1'b0; end // If previously not valid, start next transaction else if (~axi_wvalid && start_single_burst_write) begin axi_wvalid <= 1'b1; end /* If WREADY and too many writes, throttle WVALID Once asserted, VALIDs cannot be deasserted, so WVALID must wait until burst is complete with WLAST */ else if (wnext && axi_wlast) axi_wvalid <= 1'b0; else axi_wvalid <= axi_wvalid; end //WLAST generation on the MSB of a counter underflow // WVALID logic, similar to the axi_awvalid always block above always @(posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) begin axi_wlast <= 1'b0; end else if (((write_index == C_M_AXI_BURST_LEN-2 && C_M_AXI_BURST_LEN >= 2) && wnext) || (C_M_AXI_BURST_LEN == 1 )) begin axi_wlast <= 1'b1; end else if (wnext) axi_wlast <= 1'b0; else if (axi_wlast && C_M_AXI_BURST_LEN == 1) axi_wlast <= 1'b0; else axi_wlast <= axi_wlast; end always @(posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 || start_single_burst_write == 1'b1) begin write_index <= 0; end else if (wnext && (write_index != C_M_AXI_BURST_LEN-1)) begin write_index <= write_index + 1; end else write_index <= write_index; end /* Write Data Generator Data pattern is only a simple incrementing count from 0 for each burst */ always @(posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) axi_wdata <= 'b1; //else if (wnext && axi_wlast) // axi_wdata <= 'b0; else if (wnext) axi_wdata <= axi_wdata + 1; else axi_wdata <= axi_wdata; end //---------------------------- //Write Response (B) Channel //---------------------------- always @(posedge M_AXI_ACLK) begin if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) begin axi_bready <= 1'b0; end // accept/acknowledge bresp with axi_bready by the master // when M_AXI_BVALID is asserted by slave else if (M_AXI_BVALID && ~axi_bready) begin axi_bready <= 1'b1; end // deassert after one clock cycle else if (axi_bready) begin axi_bready <= 1'b0; end // retain the previous value else axi_bready <= axi_bready; end //Flag any write response errors assign write_resp_error = axi_bready & M_AXI_BVALID & M_AXI_BRESP[1];
vivado中许多IP核都采用AXI通信协议,理解AXI协议有助于后续开发工作,详细信息推荐官方文件ug1037以及ihi0022c
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。