zoukankan      html  css  js  c++  java
  • AXI4的主机协议代码分析

    AXI4的主机协议代码分析

    一、模块分析

    (1)端口列表

            input wire  INIT_AXI_TXN,
            // Asserts when ERROR is detected
            output reg  ERROR,
            // Asserts when AXI transactions is complete
            output wire  TXN_DONE,
            // AXI clock signal
            input wire  M_AXI_ACLK,
            // AXI active low reset signal
            input wire  M_AXI_ARESETN,
            // Master Interface Write Address Channel ports. Write address (issued by master)
            output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
            // Write channel Protection type.
        // This signal indicates the privilege and security level of the transaction,
        // and whether the transaction is a data access or an instruction access.
            output wire [2 : 0] M_AXI_AWPROT,
            // Write address valid. 
        // This signal indicates that the master signaling valid write address and control information.
            output wire  M_AXI_AWVALID,
            // Write address ready. 
        // This signal indicates that the slave is ready to accept an address and associated control signals.
            input wire  M_AXI_AWREADY,
            // Master Interface Write Data Channel ports. Write data (issued by master)
            output wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_WDATA,
            // Write strobes. 
        // This signal indicates which byte lanes hold valid data.
        // There is one write strobe bit for each eight bits of the write data bus.
            output wire [C_M_AXI_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB,
            // Write valid. This signal indicates that valid write data and strobes are available.
            output wire  M_AXI_WVALID,
            // Write ready. This signal indicates that the slave can accept the write data.
            input wire  M_AXI_WREADY,
            // Master Interface Write Response Channel ports. 
        // This signal indicates the status of the write transaction.
            input wire [1 : 0] M_AXI_BRESP,
            // Write response valid. 
        // This signal indicates that the channel is signaling a valid write response
            input wire  M_AXI_BVALID,
            // Response ready. This signal indicates that the master can accept a write response.
            output wire  M_AXI_BREADY,
            // Master Interface Read Address Channel ports. Read address (issued by master)
            output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
            // Protection type. 
        // This signal indicates the privilege and security level of the transaction, 
        // and whether the transaction is a data access or an instruction access.
            output wire [2 : 0] M_AXI_ARPROT,
            // Read address valid. 
        // This signal indicates that the channel is signaling valid read address and control information.
            output wire  M_AXI_ARVALID,
            // Read address ready. 
        // This signal indicates that the slave is ready to accept an address and associated control signals.
            input wire  M_AXI_ARREADY,
            // Master Interface Read Data Channel ports. Read data (issued by slave)
            input wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_RDATA,
            // Read response. This signal indicates the status of the read transfer.
            input wire [1 : 0] M_AXI_RRESP,
            // Read valid. This signal indicates that the channel is signaling the required read data.
            input wire  M_AXI_RVALID,
            // Read ready. This signal indicates that the master can accept the read data and response information.
            output wire  M_AXI_RREADY

    识别方法:M_AXI作为前缀,表明是主机的AXI协议变量。AR开头的是读地址,AW开头的是写地址,R开头的是读数据,W开头的是写数据,B开头的是写响应。这是五个通道的基本判断(前面是后面的必要条件,但不是充分条件,即AR不一定是读地址,例如ARESETN是低电平复位信号,具体的看英文注释即可判断)。

    (2)clogb2函数

    function integer clogb2 (input integer bit_depth);
             begin
             for(clogb2=0; bit_depth>0; clogb2=clogb2+1)
                 bit_depth = bit_depth >> 1;
             end
    endfunction

    这个函数的功能就是返回一个整型变量的位宽深度(也就是二进制的有效数据,排除前面的多余0所剩下的位宽)。

    (3)内部信号声明

    xilinx的IP中端口信号一定是大写的,内部使用信号则是小写,方便阅读时判断信号是否为端口列表中的信号。端口信号需要考虑和其他模块连接的问题,二内部信号则没有这么多的考虑。

    (4)初始化信号init_txn_ff2

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

    采用两级reg延时将INIT_AXI_TXN初始化信号接收过来。

    (5)写地址通道的实现

    always @(posedge M_AXI_ACLK)                                              
          begin                                                                        
            //Only VALID signals must be deasserted during reset per AXI spec          
            //Consider inverting then registering active-low reset for higher fmax     
            if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                   
              begin                                                                    
                axi_awvalid <= 1'b0;                                                   
              end                                                                      
              //Signal a new address/data command is available by user logic           
            else                                                                       
              begin                                                                    
                if (start_single_write)                                                
                  begin                                                                
                    axi_awvalid <= 1'b1;                                               
                  end                                                                  
             //Address accepted by interconnect/slave (issue of M_AXI_AWREADY by slave)
                else if (M_AXI_AWREADY && axi_awvalid)                                 
                  begin                                                                
                    axi_awvalid <= 1'b0;                                               
                  end                                                                  
              end                                                                      
          end

    使用开始写入信号触发写地址通道的握手信号。写通道初始信号也是由其控制的。

    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        

    (6)写数据通道的实现

    由于前面在从机的时候就详细地介绍了如何区分每个信号的作用。这里不再列举代码,对源码感兴趣的可以在vivado的工程中寻找。这里关注如何理解这些信号的变化,为理解时序图打下基础。

    axi_wvalid受start_single_write控制拉高,由其他信号拉低。这个实际上需要对整个数据传输的流程有所认识,这里不做解释。

    (7)写响应通道

    axi_bready:等待握手信号,等待从机发送写完成后握手信号。

    (8)读地址通道

    read_index:读初始化信号

    axi_arvalid:读地址通道的握手信号。

    (9)读数据通道

    axi_rready:读数据等待握手信号。

    read_resp_error:读数据错误信号。

    这里的基本功能和从机的lite形似,但是,作为主机,其还有重要的逻辑需要实现。在基本的通道构建完成后,还需要对其作为主机的协调和链接选择的功能实现。

    二、系统功能

    (1)写入地址

     axi_awaddr在M_AXI_AWREADY和axi_awvalid握手成功后即写入地址32'h0000_0004的地址位。

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

    (2)写入数据

    axi_wdata在写入数据握手成功后即可将初始化的数据write_index写入数据通道。具体实现和前面的写入地址是一致的。

    (3)读地址

    将axi_araddr通道加上想要读的地址即可实现。和前面的实现方式一样,都是等待握手成功后完成地址操作。由expected_rdata实现地址的接收。

    (4)指令连接状态机

    IDLE负责实现所有信号初始化。INIT_WRITE负责将初始化写信号。INIT_READ负责初始化读信号。INIT_COMPARE负责处理读写冲突信号。具有报错的作用。具体实现方法在代码中可以一一看到。

    (5)终端写入统计

    通过一个last_write信号表明写入数据的结束。可以切入时钟刻度得到数据写入的数量。

    (6)最后写入校对

    writes_done可以完成用于和last_write比较,校对写入的数据是否有正确的写响应信号。

    (7)终端读取统计

    last_read可以判断最后一位数据的读取完成。

    (8)最后读取校对

    reads_done可以在last_read基础上加上读握手判断,用于判断读数据是否成功。

    (9)报错机制

    read_mismatch用于数据的判断读信号是否匹配。error_reg用于判断存储的数据和传输的数据是否匹配。判断方法就是是否有错误的信号。

    三、总结反思

    相对于AXI4从机的协议,主机需要的内容显然更多,抽象的层次也不一样。从机可以直接得到通道的信号得到数据,而主机则需要更多的判断机制。需要使用线路判断逻辑和错误信号判断逻辑来支持数据的传输。这些额外的逻辑需要认真学习。事实上,其他的传输逻辑也是需要这些部分的辅助的。这个学会了,其他的也就触类旁通了。

  • 相关阅读:
    网店系统H5版(一)
    php date()方法传入时间戳为空时返回1970-01-01
    MySQL实用语句
    HTTPS和SSL握手过程(转载)
    jinfo
    linux下以‘-’开头的文件名
    ssh连接服务器失败解决记录
    Linux时区详解
    fiddler抓包url有乱码
    mysql灾备演练问题
  • 原文地址:https://www.cnblogs.com/electricdream/p/13584493.html
Copyright © 2011-2022 走看看