S_AXI_REG接口时序设计纪要

axi_wready使用了自反控制,当其他条件满足时,就跳转状态。axi_wready为拉低状态时,表示处于等待状态,检测AW和W通道的V握手,以及latch使能状态,满足条件时,产生R握手,并跳转到R握手状态。

if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID && aw_en )
	        begin
	          axi_wready <= 1'b1;
	        end
	      else
	        begin
	          axi_wready <= 1'b0;
	        end

axi_awready使用了自反控制,当其他条件满足时,就跳转状态。axi_awready为拉低状态时,表示处于等待状态,检测AW和W通道的V握手,以及latch使能状态,满足条件时,产生R握手,并跳转到R握手状态。

if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
	        begin
	          axi_awready <= 1'b1;
	        end
	      else           
	        begin
	          axi_awready <= 1'b0;
	        end

其中的关键控制信号,是aw_en。
来看看aw_en,
aw_en也用了自反控制,但是为了防止死锁,复位时,aw_en的初态是拉高有效。
当接口拉高axi_awready的同时,aw_en被拉低。表示不再能够latch。直到B通道的VR握手成功,才再次拉高,表示能够latch。

always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      	aw_en <= 1'b1;
	    end 
	  else
	    begin    
	      if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
	        begin
	          aw_en <= 1'b0;
	        end
	        else if (S_AXI_BREADY && axi_bvalid)
	            begin
	              aw_en <= 1'b1;
	            end
	    end 
	end    

可以看出,aw_en的latch状态,依赖于B通道的VR握手。
来看看axi_bvalid,
axi_bvalid也使用了自反控制,当其他条件满足时,就跳转状态。当axi_bvalid为拉低状态时,表示处于等待状态,可以产生下一个V握手。当axi_bvalid为拉高状态时,表示处于V握手状态,正在检测对端的R握手。一旦检测到R握手,那么就跳转到等待状态。

always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_bvalid  <= 0;
	    end 
	  else
	    begin    
	      if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID)
	        begin
	         	          axi_bvalid <= 1'b1;
	        end                  
	      else
	        begin
	          if (S_AXI_BREADY && axi_bvalid) 
	            begin
	              axi_bvalid <= 1'b0; 
	            end  
	        end
	    end
	end  

来看看axi_awaddr,它的latch条件和axi_awready的拉高条件是一样的,所以接口在锁存了AWADDR的同时,拉高了AWREADY,通知对端可以修改。

always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_awaddr <= 0;
	    end 
	  else
	    begin    
	      if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
	        begin
	         	 axi_awaddr <= S_AXI_AWADDR;
	        end
	    end 
	end 

来看看slv_reg_wren,它的信号状态,依赖于AW和W通道的VR握手状态。
对于S_AXI接口而言,当axi_awaddr成功锁存的同时,就会一起拉高axi_wready和 axi_awready。在下一个周期,被锁存的axi_awaddr就可以被使用了。

assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;

来看看slv_reg0。
它受控于slv_reg_wren的状态,且根据前一周期锁存的axi_awaddr的地址,进行分支判断,当满足地址条件时,将WDATA的数据,锁存到slv_reg0中。
这里可以看出,锁存axi_awaddr会比锁存slv_reg0提前一个周期。
slv_reg0锁存然后输出的节拍点,是AW通道和W通道,检测到VR握手的节拍点。

always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      slv_reg0 <= 0; 
	    end 
	  else begin
	    if (slv_reg_wren)
	      begin
	        case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
	          6'h00:
	            for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
	              if ( S_AXI_WSTRB[byte_index] == 1 ) begin
	                // Respective byte enables are asserted as per write strobes 
	                // Slave register 0
	                slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
	              end  
	          default : begin
	                      slv_reg0 <= slv_reg0;
	                  end
	        endcase
	      end
	  end
	end   

再来看axi_arready。
axi_arready,
axi_arready使用了自反控制,当其他条件满足时,就跳转状态。axi_arready为拉低状态时,表示处于等待状态,检测AR通道的V握手,满足条件时,产生R握手,并跳转到R握手状态。

always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_arready <= 1'b0;
	    end 
	  else
	    begin    
	      if (~axi_arready && S_AXI_ARVALID)
	        begin
	          axi_arready <= 1'b1; 
	        end
	      else
	        begin
	          axi_arready <= 1'b0;
	        end
	    end 
	end  

来看看axi_araddr,
当axi_arready满足条件,从等待状态跳转到R握手状态的同时,axi_araddr锁存ARADDR。下一个周期,就可以使用这个锁存好的axi_araddr了。

always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	     	axi_araddr  <= 32'b0;
	    end 
	  else
	    begin    
	      if (~axi_arready && S_AXI_ARVALID)
	        begin
	            axi_araddr  <= S_AXI_ARADDR;
	        end
	    end 
	end   

来看看reg_data_out。
它利用锁存好的axi_araddr进行分支判断,当地址条件满足时,选择对应的reg_in。

always @(*)
	begin
	      // Address decoding for reading registers
	      case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
	        6'h00   : reg_data_out <= slv_reg0;
	        6'h01   : reg_data_out <= reg1_in;
	        6'h02   : reg_data_out <= reg2_in;
	        6'h03   : reg_data_out <= reg3_in;
	        default : reg_data_out <= 0;
	      endcase
	end

来看看axi_rvalid。
axi_rvalid使用了自反控制,当其他条件满足时,就跳转状态。当axi_rvalid为拉低状态时,表示处于等待状态,可以产生下一个V握手。当axi_rvalid为拉高状态时,表示处于V握手状态,正在检测对端的R握手。一旦检测到R握手,那么就跳转到等待状态。
可以看出,锁存了axi_araddr的下一个周期,才会生成axi_rvalid的拉高有效。

always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_rvalid <= 0;
	    end 
	  else
	    begin    
	      if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)
	        begin
	         	  axi_rvalid <= 1'b1;
	        end   
	      else if (axi_rvalid && S_AXI_RREADY)
	        begin
	          	  axi_rvalid <= 1'b0;
	        end                
	    end
	end 

来看看slv_reg_rden。它的信号状态,依赖于AR通道的VR握手状态,以及RVALID的等待状态。
这里可以看出,这个信号的条件,其实就是axi_rvalid拉高有效的条件。

assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;

来看看axi_rdata。
它受控于slv_reg_rden信号。
这里可以看出,axi_rdata的锁存条件,和axi_rvalid的生成条件是一样的。所以,axi_data和axi_rvalid是同时打出数据的。
另外,锁存了axi_araddr的下一个周期,才会生成axi_rvalid的拉高有效。而axi_data和axi_rvalid是同时打出数据的,所以,axi_data的打出,比锁存axi_araddr,晚一个周期。

always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_rdata  <= 0;
	    end 
	  else
	    begin    
	      if (slv_reg_rden)
	        begin
	          axi_rdata <= reg_data_out;     // register read data
	        end   
	    end
	end   

来看看reg0_out。
从S_AXI接口接收的数据,如果需要向外引出,那么如下代码即可。
来看看reg0_out。
从S_AXI接口接收的数据,如果需要向外引出,那么如下代码即可。

assign reg0_out = slv_reg0;

来看看reg1_in。
从外部输入的数据,如果想从S_AXI接口发送出去,那么如下代码即可。

always @(*)
	begin
	      // Address decoding for reading registers
	      case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
	        6'h00   : reg_data_out <= slv_reg0;
	        6'h01   : reg_data_out <= reg1_in;
	        6'h02   : reg_data_out <= reg2_in;
	        6'h03   : reg_data_out <= reg3_in;
	        default : reg_data_out <= 0;
	      endcase
	end
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值