AXI_lite_PL

ZYNQ AXI协议学习(AXI_Lite,PL端为主机)

上一篇文章分析了AXI_Lite总线PS端为主机,PL端为从机的通讯方式

创建一个AXI_lite接口的IP核(PL为主机)vivado版本用的2019

在这里插入图片描述

对于上面一些端口的理解

status,状态组里面,INIT_AXI_TXN是一个开始触发信号,ERROR和TXN_DONE是用来判断读写错误和读写完成的信号

还是和上一篇文章一样,先在线仿真,在进行代码得分析

写操作(PL->PS)

使用官方的代码进行在线DEbug,分析代码

在这里插入图片描述

注:图上是没有INIT_AXI_TXN信号的,

assign init_txn_pulse	= (!init_txn_ff2) && init_txn_ff;//检测上升沿

//Generate a pulse to initiate AXI transaction.
always @(posedge M_AXI_ACLK)										      
  begin                                                                        
    // Initiates AXI transaction delay    
    if (M_AXI_ARESETN == 0 )                                                   
      begin                                                                    
        init_txn_ff <= 1'b0;                                                   
        init_txn_ff2 <= 1'b0;                                                   
      end                                                                               
    else                                                                       
      begin  
        init_txn_ff <= INIT_AXI_TXN;
        init_txn_ff2 <= init_txn_ff;                                                                 
      end                                                                      
  end     

这里就是开始信号的逻辑,来一个上升沿就会触发

写操作分析

由在线的仿真图可以看出,写数据和写地址是同时发生的,AWREADY和WREADY一直为高,说明PS端一直处于写准备好状态。

对于AWPROT端口:
    assign M_AXI_AWPROT	= 3'b000; 代码中直接赋值为000,这里就不用理会。
WTRSB端口:
    assign M_AXI_WSTRB	= 4'b1111;一样没什么意义。

除去这些固定端口,剩下的好分析了。

这里只分析关键代码,剩余的可以参考仿真图与源码自己查看

写地址:

	assign M_AXI_AWADDR	= C_M_TARGET_SLAVE_BASE_ADDR + axi_awaddr;//初始地址加上偏移地址
    代码的初始地址是0x40000000,这里我修改为了0x10000000,因为我板子只有512M的内存

	  //Write Addresses                                        
        always @(posedge M_AXI_ACLK)                                  
            begin                                                     
                if (M_AXI_ARESETN == 0  || init_txn_pulse == 1'b1)                                
                begin                                                 
                    axi_awaddr <= 0;                                    
                end                                                   
                // Signals a new write address/ write data is         
                // available by user logic                            
                else if (M_AXI_AWREADY && axi_awvalid)                  
                begin                                                 
                    axi_awaddr <= axi_awaddr + 32'h00000004;            
                                                                        
                end                                                   
            end  
    开始信号到来复位偏移地址,写地址有效(在仿真图里可以看到,只有一个周期的高电平)加上一个4的偏移地址等待下一次写

写数据:

parameter  C_M_START_DATA_VALUE	= 32'hAA000000,
//测试数据,赋予初始值

    	  // Write data generation                                      
        always @(posedge M_AXI_ACLK)                                  
            begin                                                     
                if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                                
                begin                                                 
                    axi_wdata <= C_M_START_DATA_VALUE;                  
                end                                                   
                // Signals a new write address/ write data is           
                // available by user logic                              
                else if (M_AXI_WREADY && axi_wvalid)                    
                begin                                                 
                    axi_wdata <= C_M_START_DATA_VALUE + write_index;    
                end                                                   
                end 
    逻辑和写地址一样,写数据有效就加1(write_index),仿真图也能看出数据每次加1。

    	  always @(posedge M_AXI_ACLK)                                                 
            begin                                                                        
                if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                   
                begin                                                                    
                    write_index <= 0;                                                      
                end                                                                      
                // Signals a new write address/ write data is                            
                // available by user logic                                               
                else if (start_single_write)                                               
                begin                                                                    
                    write_index <= write_index + 1;                                        
                end                                                                      
            end 

    该逻辑就是write_index的加法逻辑,start_single_write该信号有效就加1
    start_single_write该信号的高低跳变在状态机写逻辑里面,该信号也是写操作一次跳变一次(一个周期)

写回应:

	  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 write errors                                                    
assign write_resp_error = (axi_bready & M_AXI_BVALID & M_AXI_BRESP[1]);

M_AXI_BRESP信号的第1位用于判断是否写入错误

读操作(PL->PS)

使用官方的代码进行在线DEbug,分析代码

在这里插入图片描述

读操作分析

在读地址通道,ARREADY信号一直处于高电平,PS端一直处于读地址准备好的状态。

ARPROT端口:
    assign M_AXI_ARPROT	= 3'b001;//这里直接赋值

读地址:

assign M_AXI_ARADDR	= C_M_TARGET_SLAVE_BASE_ADDR + axi_araddr;
//和写地址一样也是初始地址加上读偏移地址
	  //Read Addresses                                              
  always @(posedge M_AXI_ACLK)                                  
      begin                                                     
        if (M_AXI_ARESETN == 0  || init_txn_pulse == 1'b1)                                
          begin                                                 
            axi_araddr <= 0;                                    
          end                                                   
          // Signals a new write address/ write data is         
          // available by user logic                            
        else if (M_AXI_ARREADY && axi_arvalid)                  
          begin                                                 
            axi_araddr <= axi_araddr + 32'h00000004;            
          end                                                   
      end  
这个逻辑是每读一次,偏移地址加4(默认的偏移地址是0)

读数据:

 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 && ~axi_rready)                               
      begin                                                             
        axi_rready <= 1'b1;                                             
      end                                                               
    // deassert after one clock cycle                                   
    else if (axi_rready)                                                
      begin                                                             
        axi_rready <= 1'b0;                                             
      end                                                               
    // retain the previous value                                        
  end                                                                   
                                                                        
//Flag write errors                                                     
assign read_resp_error = (axi_rready & M_AXI_RVALID & M_AXI_RRESP[1]);  //判断是否读取成功

当M_AXI_RVALID拉高后,PL端拉高rready信号,读取数据

状态机分析

在这里插入图片描述

该代码存在4个状态,空闲(IDLE),写状态(INIT_WRITE),读状态(INIT_READ),比较状态(INIT_CONPARE)

默认初始化处于空闲状态,开始信号触发后,跳转至写状态,写满4个数据(C_M_TRANSACTIONS_NUM = 4),跳转至读状态,读取刚才写入的4个数据。跳转至比较状态进行数据对比,对比完成后跳转至空闲信号等待下一次的数据操作

结语

上面分析的是一些主要的代码,官方的这个IP源码只能用于自己学习使用。状态机在应用中是不需要的,也没有人的项目是先写数据再去读数据吧。

AXI_Lite接口看仿真图和以前的分析可得,不适合数据量大的情况,没有突发传输。当数据量太多之后还是得使用哪个AXI接口(HP)。

感觉这个接口用处不大,就没有写自己的工程代码
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值