AXI总线代码详细整理(一)

说明

文字说明来自"AMBA® AXI™ and ACE™ ProtocolSpecification",百度直接可以搜到。
代码源自Xilinx的AXI IP,获取方法如下:
在这里插入图片描述
选择create and package new IP.
在这里插入图片描述
在这里插入图片描述
Interface Mode 选择 Master,Interface Type 选择 Full, Date Width自行设定,这里选择32.
在这里插入图片描述
选择edit IP.
本文整理了master的部分代码,后续有时间会整理master部分剩下的代码和slave的代码,因为学习协议去看文档非常枯燥,还是与代码结合比较有效,当做一个学习笔记。

1. AXI 的时钟与复位

1.1 时钟

Each AXI component uses a single clock signal, ACLK. All input signals are sampled on the rising edge of ACLK. 
All output signal changes must occur after the rising edge of ACLK.

代码:

		// Global Clock Signal.
		input wire  M_AXI_ACLK,

1.2 复位

The AXI protocol uses a single active LOW reset signal, ARESETn. The reset signal can be asserted 
asynchronously, but deassertion must be synchronous with a rising edge of ACLK.

引脚定义:
master:

		// Global Reset Singal. This Signal is Active Low
		input wire  M_AXI_ARESETN,

复位的作用引脚为:

a master interface must drive ARVALID, AWVALID, and WVALID LOW

2. 五个通道

如图所示:
在这里插入图片描述

2.1 Write Address Channel

相关信号:

signalsourcedescription
AWVALIDmasterWrite address valid. This signal indicates that the channel is signaling valid write address and control information.
AWREADYslaveWrite address valid. This signal indicates that the channel is signaling valid write address and control information.
AWADDRmasterWrite address. The write address gives the address of the first transfer in a write burst transaction.

代码:

always @(posedge M_AXI_ACLK)                                   
	  begin                                                                
	                                                                       
	    if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                                           
	      begin                                                            
	        axi_awvalid <= 1'b0;                                           
	      end                                                              
	    // If previously not valid , start next transaction                
	    else if (~axi_awvalid && start_single_burst_write)                 
	      begin                                                            
	        axi_awvalid <= 1'b1;                                           
	      end                                                              
	    /* Once asserted, VALIDs cannot be deasserted, so axi_awvalid      
	    must wait until transaction is accepted */                         
	    else if (M_AXI_AWREADY && axi_awvalid)                             
	      begin                                                            
	        axi_awvalid <= 1'b0;                                           
	      end                                                              
	    else                                                               
	      axi_awvalid <= axi_awvalid;                                      
	    end     

这一段代码即为握手过程:

Once VALID is asserted it must remain asserted until the handshake occurs, at a rising clock edge at which VALID and READY are both asserted.

在这里插入图片描述
在这里插入图片描述
代码:

// Next address after AWREADY indicates previous address acceptance    
	  always @(posedge M_AXI_ACLK)                                         
	  begin                                                                
	    if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                            
	      begin                                                            
	        axi_awaddr <= 'b0;                                             
	      end                                                              
	    else if (M_AXI_AWREADY && axi_awvalid)                             
	      begin                                                            
	        axi_awaddr <= axi_awaddr + burst_size_bytes;                   
	      end                                                              
	    else                                                               
	      axi_awaddr <= axi_awaddr;                                        
	    end   

这里init_txn_pulse是初始标志,将axi_awvalid清零和axi_awaddr地址归到起始。
如前面所说,AWADDR是每次burst传输的首地址,因此每次加一个burst_size_bytes。
burst_size_bytes定义为:

assign burst_size_bytes	= C_M_AXI_BURST_LEN * C_M_AXI_DATA_WIDTH/8;

即长度×宽度/8(字节),这里涉及到突发传输的长度宽度,可以看3.1。

2.2 Write Data Channel

相关信号:

signalsourcedescription
WVALIDmasterWrite valid. This signal indicates that valid write data and strobes are available.
WREADYslaveWrite ready. This signal indicates that the slave can accept the write data.
WLASTmasterWrite last. This signal indicates the last transfer in a write burst.
WDATAmasterWrite data.

代码:

// 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 (M_AXI_WREADY & axi_wvalid&& axi_wlast)                                                    
	      axi_wvalid <= 1'b0;                                                           
	    else                                                                            
	      axi_wvalid <= axi_wvalid;                                                     
	  end             

这一段和上面的握手过程类似,不同的是WVALID需要在axi_wlast为1时清零。
代码:

//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                                                                           
	    // axi_wlast is asserted when the write index                                   
	    // count reaches the penultimate count to synchronize                           
	    // with the last write data 
	    else if (((write_index == C_M_AXI_BURST_LEN-2 && C_M_AXI_BURST_LEN >= 2) && M_AXI_WREADY & axi_wvalid) || (C_M_AXI_BURST_LEN == 1 ))
	      begin                                                                         
	        axi_wlast <= 1'b1;                                                          
	      end                                                                           
	    // Deassrt axi_wlast when the last write data has been                          
	    // accepted by the slave with a valid response                                  
	    else if (M_AXI_WREADY & axi_wvalid)                                                                 
	      axi_wlast <= 1'b0;                                                            
	    else if (axi_wlast && C_M_AXI_BURST_LEN == 1)                                   
	      axi_wlast <= 1'b0;                                                            
	    else                                                                            
	      axi_wlast <= axi_wlast;                                                       
	  end    

C_M_AXI_BURST_LEN为burst的长度,在长度大于等于2时,write_index为C_M_AXI_BURST_LEN-2时wlast置1,如果长度为1则直接置1。在最后一个数据被接收后wlast清零。
代码,write_index:

/* 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_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,这里给出的是简单的每次增加1的data

/* 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

2.3 Write Response (B) Channel

相关信号:

signalsourcedescription
BVALIDslaveWrite response valid. This signal indicates that the channel is signaling a valid write response.
BREADYmasterResponse ready. This signal indicates that the master can accept a write response.

代码:

 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 

这是握手过程,是上面两段握手的反过程,valid由slave发送,ready由master发送。ready仅发送一个时钟。

2.4 Read Address Channel

signalsourcedescription
ARVALIDmasterRead address valid. This signal indicates that the channel is signaling valid read address and control information.
ARREADYsalveRead address ready. This signal indicates that the slave is ready to accept an address and associated control signals.
ARADDRmasterRead address. The read address gives the address of the first transfer in a read burst transaction.

握手机制代码:

	  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

地址增加代码,这里和写地址十分类似:

	  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   

2.5 Read Data (and Response) Channel

signalsourcedescription
RLASTslaveRead last. This signal indicates the last transfer in a read burst.
RVALIDsalveRead valid. This signal indicates that the channel is signaling the required read data.
RREADYmasterRead ready. This signal indicates that the master can accept the read data and response information.

握手机制代码:

 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       

3 突发传输机制

3.1 突发传输长度和宽度

相关信号:

signalsourcedescription
AWLENmasterBurst length. The burst length gives the exact number of transfers in a burst. This information determines the number of data transfers associated with the address.
AWSIZEmasterBurst size. This signal indicates the size of each transfer in the burst.
ARLENmaster同AWLEN
ARSIZEmaster同ARSIZE

引脚定义(master):

output wire [7 : 0] M_AXI_AWLEN,
output wire [2 : 0] M_AXI_AWSIZE,
output wire [7 : 0] M_AXI_ARLEN,
output wire [2 : 0] M_AXI_ARSIZE,
assign M_AXI_ARLEN	= C_M_AXI_BURST_LEN - 1;
assign M_AXI_ARSIZE	= clogb2((C_M_AXI_DATA_WIDTH/8)-1);
assign M_AXI_AWLEN	= C_M_AXI_BURST_LEN - 1;
assign M_AXI_AWSIZE	= clogb2((C_M_AXI_DATA_WIDTH/8)-1);

ARLEN/AWLEN:

The burst length for AXI4 is defined as,
Burst_Length = AxLEN[7:0] + 1, to accommodate the extended burst length of the INCR burst type in AXI4.

ARSIZE/AWSIZE如下表所示:
在这里插入图片描述
都与代码是一致的。
C_M_AXI_DATA_WIDTH定义与之前定义的width是一致的:

parameter integer C_M_AXI_DATA_WIDTH	= 32,

一次传输的字节数:

assign burst_size_bytes	= C_M_AXI_BURST_LEN * C_M_AXI_DATA_WIDTH/8;

读数据通道的突发传输长度计数:
突发传输方式计数:

 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   

3.2 突发传输类型

相关信号:

signalsourcedescription
ARBURSTmasterBurst type. The burst type and the size information determine how the address for each transfer within the burst is calculated.
AWBURSTmaster同ARBURST

引脚定义(master):

output wire [1 : 0] M_AXI_AWBURST,
output wire [1 : 0] M_AXI_ARBURST

不同的ARBURST/AWBURST对应的突发传输类型如下表,具体的机制需要分析slave的代码 (slave的代码后续有时间也会整理)。
在这里插入图片描述
同时突发传输长度也与突发传输类型有关,突发传输长度的规定:

AXI4 extends burst length support for the INCR burst type to 1 to 256 transfers. Support for all other burst types in AXI4 remains at 1 to 16 transfers.
  • 6
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值