ZYNQ之路--Xilinx AXI-Full-Master实例代码翻译

这篇具有很好参考价值的文章主要介绍了ZYNQ之路--Xilinx AXI-Full-Master实例代码翻译。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

代码解析


前言

        在我学习过程中遇到了第一个认知上的门槛:AXI协议。试想一个场景:我PL端的IP要通过AXI-Full协议给PS端传输数据,我该怎么做?

        首先肯定是创建一个带有AXI-Full-Matser的接口ZYNQ之路--Xilinx AXI-Full-Master实例代码翻译,佛系学FPGA&&数字设计,fpga开发,嵌入式硬件,硬件工程,学习

         下一步,Xilinx官方会给我们一个接口的实例文件:

ZYNQ之路--Xilinx AXI-Full-Master实例代码翻译,佛系学FPGA&&数字设计,fpga开发,嵌入式硬件,硬件工程,学习

         顶层是一个对外的接口,而内层的代码则是AXI-Full-Master接口的协议实现。当然了,我们肯定是要通过改动这个文件来将我们自己的IP和AXI接口协议相结合,因此我们有必要读懂AXI-Full-Master的代码内容。

代码解析

        实际上Xilinx官方给的这个例子是一个AXI-Full-Master读写的例子,一共900多行,主要是描述一个带有AXI-Master接口的IP要如何进行数据的读写。

ZYNQ之路--Xilinx AXI-Full-Master实例代码翻译,佛系学FPGA&&数字设计,fpga开发,嵌入式硬件,硬件工程,学习

         相当于描述了一个这样的状态机,初始化完之后先开始写,再开始读,并且把读出的数据和写入的比较,如果没有错误即可开始新一轮的写。

        代码具有参考加载,能够指导我们编写符合AXI协议规范的IP。

我将英文翻译成为中文,供各位研究,同时红色部分是我重点标出来,可供大家思考与改造。

`timescale 1 ns / 1 ps

    module M_AXI_Test1_v1_0_M_AXI #
    (

        // 目标从机基地址
        parameter  C_M_TARGET_SLAVE_BASE_ADDR    = 32'h40000000,
        // 突发长度. 支持 1, 2, 4, 8, 16, 32, 64, 128, 256
        parameter integer C_M_AXI_BURST_LEN    = 16,
        // 线程ID宽度
        parameter integer C_M_AXI_ID_WIDTH    = 1,
        // 地址总线宽度
        parameter integer C_M_AXI_ADDR_WIDTH    = 32,
        // 数据总线宽度

        parameter integer C_M_AXI_DATA_WIDTH    = 32,
        // 用户写地址总线宽度
        parameter integer C_M_AXI_AWUSER_WIDTH    = 0,
        // 用户读地址总线宽度
        parameter integer C_M_AXI_ARUSER_WIDTH    = 0,
        // 用户写数据总线宽度
        parameter integer C_M_AXI_WUSER_WIDTH    = 0,
        // 用户读数据总线宽度
        parameter integer C_M_AXI_RUSER_WIDTH    = 0,
        // 用户应答总线宽度
        parameter integer C_M_AXI_BUSER_WIDTH    = 0
    )
    (
        
        /*
            端口定义块,该模块定义了AXI-Full-Master的各个接口,包括了:
            1、时钟、复位、传输状态标志、AXI接口ID、用户自定义通道
            2、写数据通道(写地址、写数据、写响应)
            3、读数据通道(读地址、读数据)
        */
        
        // AXI启动线
        input wire  INIT_AXI_TXN, //异步信号
        // 当传输完成时置位
        output wire  TXN_DONE,
        // 当检测到错误时置位
        output reg  ERROR,
        // 全局时钟信号
        input wire  M_AXI_ACLK,
        // 全局复位信号,低电平有效
        input wire  M_AXI_ARESETN,


/*写通道信号*/

        // 主机接口写地址ID
        output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_AWID,
        // 突发长度. (The burst length gives the exact number of transfers in a burst)
        output wire [7 : 0] M_AXI_AWLEN,
        // 突发传输的大小. (This signal indicates the size of each transfer in the burst)
        output wire [2 : 0] M_AXI_AWSIZE,
        // 突发类型. (The burst type and the size information), 
    // determine how the address for each transfer within the burst is calculated。
    //决定了每次突发传输的地址是怎样计算出的
        output wire [1 : 0] M_AXI_AWBURST,
        // Lock type. Provides additional information about the
    // atomic characteristics of the transfer.
//锁定类型,提供关于传输的原子特征的附加信息
        output wire  M_AXI_AWLOCK,
        // 存储类型. This signal indicates how transactions
        // are required to progress through a system.
        //这个信号指示了数据传输如何在系统中进行
        output wire [3 : 0] M_AXI_AWCACHE,
        // 保护类型. 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,
        // 服务质量, QoS identifier sent for each write transaction.
        //为每个写事务发送的QoS标识符。
        output wire [3 : 0] M_AXI_AWQOS,
        // Optional User-defined signal in the write address channel.
        //可选写地址通道中的自定义信号
        output wire [C_M_AXI_AWUSER_WIDTH-1 : 0] M_AXI_AWUSER,

//写地址信号组
        //主机接口写地址
        output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
        // 写地址有效 This signal indicates that
    // the channel is signaling valid write address and control information.
    //该信号指示该通道正在发送有效的写地址和控制信息
        output wire  M_AXI_AWVALID,
        // 写地址准备. This signal indicates that
    // the slave is ready to accept an address and associated control signals
    //该信号指示从机已经准备好接收地址和相关控制信号
        input wire  M_AXI_AWREADY,
        
//写数据信号组
        // 主机写数据接口
        output wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_WDATA,
        // 写选通. 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,
        // 上一次写信号. This signal indicates the last transfer in a write burst.
        //这个信号指示了在指示写突发中的最后一次传输
        output wire  M_AXI_WLAST,
        // Optional User-defined signal in the write data channel.
        //可选写数据通道中的自定义信号
        output wire [C_M_AXI_WUSER_WIDTH-1 : 0] M_AXI_WUSER,
        // 写有效信号. This signal indicates that valid write
    // data and strobes are available
    //此信号指示了写数据和选通信号有效
        output wire  M_AXI_WVALID,
        // 写准备信号. This signal indicates that the slave
    // can accept the write data.
    //该信号指示从机已经准备好接收写入的数据
        input wire  M_AXI_WREADY,


//写响应信号组
        // Master Interface Write Response.
        input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_BID,
        // 写响应信号. This signal indicates the status of the write transaction.
        //该信号指示写传输的状态
        input wire [1 : 0] M_AXI_BRESP,
        // Optional User-defined signal in the write response channel
        //可选写响应通道中的自定义信号
        input wire [C_M_AXI_BUSER_WIDTH-1 : 0] M_AXI_BUSER,
        // 写响应有效. This signal indicates that the
    // channel is signaling a valid write response.
    //该信号指示通道正在发送有效的写响应
        input wire  M_AXI_BVALID,
        // 响应准备信号. This signal indicates that the master
    // can accept a write response.
    //该信号指示主机可以接收写响应信号
    
    
    
/*读数据通道*/
        output wire  M_AXI_BREADY,
        // 主机接口读地址ID.
        output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_ARID,
       
        // 突发长度. The burst length gives the exact number of transfers in a burst
        output wire [7 : 0] M_AXI_ARLEN,
        // 突发大小. This signal indicates the size of each transfer in the burst
        output wire [2 : 0] M_AXI_ARSIZE,
        // 突发类型. The burst type and the size information, 
    // determine how the address for each transfer within the burst is calculated.
        output wire [1 : 0] M_AXI_ARBURST,
        //锁定类型. Provides additional information about the
    // atomic characteristics of the transfer.
        output wire  M_AXI_ARLOCK,
        // 存储类型. This signal indicates how transactions
    // are required to progress through a system.
        output wire [3 : 0] M_AXI_ARCACHE,
        // 保护类型. 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,
        // 服务质量, QoS identifier sent for each read transaction
        output wire [3 : 0] M_AXI_ARQOS,
        // Optional User-defined signal in the read address channel.
        output wire [C_M_AXI_ARUSER_WIDTH-1 : 0] M_AXI_ARUSER,

//读地址信号组

         // 读地址. This signal indicates the initial
          // address of a read burst transaction.
        //该信号指示突发读的起始地址
        output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
        // 写入地址有效. This signal indicates that
    // the channel is signaling valid read address and control information
    //该信号指示通道正在发送有效的读地址以及相关控制信号
        output wire  M_AXI_ARVALID,
        //读地址准备信号. This signal indicates that
    // the slave is ready to accept an address and associated control signals
    //该信号指示从机已经准备好接收地址和控制信号
        input wire  M_AXI_ARREADY,

//读数据信号组

        // 读ID标签. This signal is the identification tag
        // for the read data group of signals generated by the slave.
        //该信号是由从机产生的信号的读数据组的身份标签
        input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_RID,
  
        // 主机读数据接口
        input wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_RDATA,
        // 读响应信号. This signal indicates the status of the read transfer
        input wire [1 : 0] M_AXI_RRESP,
        // 最后一次读信号. This signal indicates the last transfer in a read burst
        input wire  M_AXI_RLAST,
        // Optional User-defined signal in the read address channel.
        //可选读地址通道中的自定义信号
        input wire [C_M_AXI_RUSER_WIDTH-1 : 0] M_AXI_RUSER,
        // 读有效信号. This signal indicates that the channel
    // is signaling the required read data.
        input wire  M_AXI_RVALID,
        // 读准备信号. This signal indicates that the master can
    // accept the read data and response information.
        output wire  M_AXI_RREADY


    );


    /*    功能模块,用来根据数据大小计算数据位数    */
    // function called clogb2 that returns an integer which has the
    //value of the ceiling of the log base 2                 
      function integer clogb2 (input integer bit_depth);              
      begin                                                           
        for(clogb2=0; bit_depth>0; clogb2=clogb2+1)                   
          bit_depth = bit_depth >> 1;                                 
        end                                                           
      endfunction                                                     


    // C_TRANSACTIONS_NUM is the width of the index counter for 
    // number of write or read transaction.
    //C_TRANSACTIONS_NUM 是读写传输中的 传输数据个数计数器的宽度 ,C_M_AXI_BURST_LEN是突发长度,即一次突发传输数据的个数。
     localparam integer C_TRANSACTIONS_NUM = clogb2(C_M_AXI_BURST_LEN-1);

    // Burst length for transactions, in C_M_AXI_DATA_WIDTHs.
    // Non-2^n lengths will eventually cause bursts across 4K address boundaries.
    //突发传输长度,0到2^n的长度最终会对4K的地址范围内突发传输
     localparam integer C_MASTER_LENGTH    = 12; //即4K的数据的长度(最大)
    // total number of burst transfers is master length divided by burst length and burst size
    //突发传输的总数由突发传输大小和尺寸共同决定,C_NO_BURSTS_REQ这个值是突发传输次数计数器的位宽。
     localparam integer C_NO_BURSTS_REQ = C_MASTER_LENGTH-clogb2((C_M_AXI_BURST_LEN*C_M_AXI_DATA_WIDTH/8)-1);


    // Example State machine to initialize counter, initialize write transactions, 
    // initialize read transactions and comparison of read data with the 
    // written data words.
    /*
    这里给出一个状态机的例子,该状态机的功能为:
        1、初始化计数器
        2、初始化读写传输
        3、初始化读写数据比较
    */
    
//状态

    parameter [1:0] IDLE = 2'b00, // This state initiates AXI4Lite transaction 
            // after the state machine changes state to INIT_WRITE 
            // when there is 0 to 1 transition on INIT_AXI_TXN
    //当INIT_AXI_TXN从0变到1时,状态机从该状态转移到下一个状态,并且初始化AXI4Lite
        INIT_WRITE   = 2'b01, // This state initializes write transaction,
            // once writes are done, the state machine 
            // changes state to INIT_READ 
    //这个状态初始化写传输,并且,当写操作完成时,该状态将切换到 下一个状态(初始化读)
        INIT_READ = 2'b10, // This state initializes read transaction
            // once reads are done, the state machine 
            // changes state to INIT_COMPARE 
    //该状态将初始化读传输,并且,当读操作完成时,状态机将会跳转到下一个状态(比较状态)
        INIT_COMPARE = 2'b11; // This state issues the status of comparison 
            // of the written data with the read data    
    //该状态指示 写入的数据和读到的数据进行比较的结果


     reg [1:0] mst_exec_state; //状态变量

    // AXI4LITE signals
    //AXI4 internal temp signals
    //AXI4内部临时暂存变量
    reg [C_M_AXI_ADDR_WIDTH-1 : 0]     axi_awaddr; //地址
    reg      axi_awvalid;
    reg [C_M_AXI_DATA_WIDTH-1 : 0]     axi_wdata; //数据
    reg      axi_wlast; //写数据突发完成标志
    reg      axi_wvalid; //写有效信号
    reg      axi_bready; //写响应准备信号
    reg [C_M_AXI_ADDR_WIDTH-1 : 0]     axi_araddr;//读地址
    reg      axi_arvalid; //读地址有效
    reg      axi_rready; //读准备信号
    //write beat count in a burst
    //突发写节拍计数值,突发传输中,每传输一个数据,计数值加一,用于指示突发传输的进度
    reg [C_TRANSACTIONS_NUM : 0]     write_index;
    //read beat count in a burst
    //突发读节拍计数值
    reg [C_TRANSACTIONS_NUM : 0]     read_index;
    //size of C_M_AXI_BURST_LEN length burst in bytes
    //一次突发传输长度的大小(以字节为单位)
    wire [C_TRANSACTIONS_NUM+2 : 0]     burst_size_bytes;
    //The burst counters are used to track the number of burst transfers of C_M_AXI_BURST_LEN burst length needed to transfer 2^C_MASTER_LENGTH bytes of data.
    //突发计数器是用来跟踪传输 2^C_MASTER_LENGTH字节数据所需的 C_M_AXI_BURST_LEN突发长度的突发传输数量,也就是说完成一次突发传输值会加1,满了说明已经传输了4K的地址数据了。
    reg [C_NO_BURSTS_REQ : 0]     write_burst_counter;
    reg [C_NO_BURSTS_REQ : 0]     read_burst_counter;
    reg      start_single_burst_write;
    reg      start_single_burst_read;
    reg      writes_done;
    reg      reads_done;
    reg      error_reg;
    reg      compare_done;
    reg      read_mismatch;
    reg      burst_write_active;
    reg      burst_read_active;
    reg [C_M_AXI_DATA_WIDTH-1 : 0]     expected_rdata;
    //Interface response error flags
    //接口响应错误标志
    wire      write_resp_error;
    wire      read_resp_error;
    wire      wnext;
    wire      rnext;
    reg      init_txn_ff;
    reg      init_txn_ff2;
    reg      init_txn_edge;
    wire      init_txn_pulse;


    // I/O Connections assignments
    //输入输出接口赋值

    //I/O Connections. Write Address (AW)
    //写地址IO连接
    assign M_AXI_AWID    = 'b0;//ID号
    //The AXI address is a concatenation of the target base address + active offset range
    //AXI的地址是 目标基址+活动偏移范围
    assign M_AXI_AWADDR    = C_M_TARGET_SLAVE_BASE_ADDR + axi_awaddr;
    //Burst LENgth is number of transaction beats, minus 1
    //突发长度是传输的节拍数,最小为1
    assign M_AXI_AWLEN    = C_M_AXI_BURST_LEN - 1;
    //Size should be C_M_AXI_DATA_WIDTH, in 2^SIZE bytes, otherwise narrow bursts are used
    //突发传输大小应该是 数据总线宽度, 2^ Size字节,否则使用窄突发
    assign M_AXI_AWSIZE    = clogb2((C_M_AXI_DATA_WIDTH/8)-1);
    //INCR burst type is usually used, except for keyhole bursts
    //
    assign M_AXI_AWBURST    = 2'b01;
    assign M_AXI_AWLOCK    = 1'b0;
    //Update value to 4'b0011 if coherent accesses to be used via the Zynq ACP port. Not Allocated, Modifiable, not Bufferable. Not Bufferable since this example is meant to test memory, not intermediate cache. 
    //如果要通过Zynq ACP端口使用一致性访问,则将值更新为4’b0011。不可分配,不可修改,不可缓冲。不可缓冲,因为此示例用于测试内存,而不是中间缓存。
    assign M_AXI_AWCACHE    = 4'b0010;
    assign M_AXI_AWPROT    = 3'h0;
    assign M_AXI_AWQOS    = 4'h0;
    assign M_AXI_AWUSER    = 'b1;
    assign M_AXI_AWVALID    = axi_awvalid;
    //Write Data(W)
    //写数据
    assign M_AXI_WDATA    = axi_wdata;
    //All bursts are complete and aligned in this example
    //在该示例中,所有的突发传输都是完整且对齐的
    assign M_AXI_WSTRB    = {(C_M_AXI_DATA_WIDTH/8){1'b1}};
    assign M_AXI_WLAST    = axi_wlast;
    assign M_AXI_WUSER    = 'b0;
    assign M_AXI_WVALID    = axi_wvalid;
    //Write Response (B)
    //写响应
    assign M_AXI_BREADY    = axi_bready;
    
    //Read Address (AR)
    //读地址
    assign M_AXI_ARID    = 'b0;
    assign M_AXI_ARADDR    = C_M_TARGET_SLAVE_BASE_ADDR + axi_araddr;
    //Burst LENgth is number of transaction beats, minus 1
    assign M_AXI_ARLEN    = C_M_AXI_BURST_LEN - 1;
    //Size should be C_M_AXI_DATA_WIDTH, in 2^n bytes, otherwise narrow bursts are used
    assign M_AXI_ARSIZE    = clogb2((C_M_AXI_DATA_WIDTH/8)-1);
    //INCR burst type is usually used, except for keyhole bursts
    assign M_AXI_ARBURST    = 2'b01;
    assign M_AXI_ARLOCK    = 1'b0;
    //Update value to 4'b0011 if coherent accesses to be used via the Zynq ACP port. Not Allocated, Modifiable, not Bufferable. Not Bufferable since this example is meant to test memory, not intermediate cache. 
    assign M_AXI_ARCACHE    = 4'b0010;
    assign M_AXI_ARPROT    = 3'h0;
    assign M_AXI_ARQOS    = 4'h0;
    assign M_AXI_ARUSER    = 'b1;
    assign M_AXI_ARVALID    = axi_arvalid;
    //Read and Read Response (R)
    assign M_AXI_RREADY    = axi_rready;
    
    //Example design I/O
    //实例所设计的IO
    assign TXN_DONE    = compare_done;
    //Burst size in bytes
    //突发大小(以字节为单位)
    assign burst_size_bytes    = C_M_AXI_BURST_LEN * C_M_AXI_DATA_WIDTH/8;
    assign init_txn_pulse    = (!init_txn_ff2) && init_txn_ff;


    //Generate a pulse to initiate AXI transaction.
    //产生一个脉冲来初始化AXI传输
    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; //外接AXI启动线
            init_txn_ff2 <= init_txn_ff;                                                                 
          end                                                                      
      end     


    //--------------------
    //Write Address Channel
    //--------------------

    // The purpose of the write address channel is to request the address and 
    // command information for the entire transaction.  It is a single beat
    // of information.

    // The AXI4 Write address channel in this example will continue to initiate
    // write commands as fast as it is allowed by the slave/interconnect.
    // The address will be incremented on each accepted address transaction,
    // by burst_size_byte to point to the next address. 

    //写地址通道;
    /*
        写地址通道的目的在于请求传输所需要的地址信息和命令信息。这是一个单节拍的信息
        在这个例子中,AXI4写地址通道将会不断初始化写命令,直到从机响应连接
        并且将通过burst_size_byte,自动指向下一个地址
    */
    /*    译者注:该触发器块主要对axi_awvaild这个信号赋值,也就是地址有效信号    */
      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 */
        /*有效信号一旦置位,就必须保持,因此axi_awvalid
            必须一直保持直到传输完成*/                        
        else if (M_AXI_AWREADY && axi_awvalid) //ready信号和valid信号同时有效,则下一个时钟沿传输完成。                             
          begin                                                            
            axi_awvalid <= 1'b0;                                           
          end                                                              
        else   //否则一直保持                                                            
          axi_awvalid <= axi_awvalid;                                      
        end                                                                
                                                                           
                                                                           
    // Next address after AWREADY indicates previous address acceptance
    // 译者注:该模块主要对axi_awaddr信号赋值用于突发传输时控制地址递增,修改该模块可以操作写地址 
      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;   //每次地址增加burst_size_bytes                
          end                                                              
        else                                                               
          axi_awaddr <= axi_awaddr;                                        
        end                                                                


    //--------------------
    //Write Data Channel
    //--------------------

    //The write data will continually try to push write data across the interface.

    //The amount of data accepted will depend on the AXI slave and the AXI
    //Interconnect settings, such as if there are FIFOs enabled in interconnect.

    //Note that there is no explicit timing relationship to the write address channel.
    //The write channel has its own throttling flag, separate from the AW channel.

    //Synchronization between the channels must be determined by the user.

    //The simpliest but lowest performance would be to only issue one address write
    //and write data burst at a time.

    //In this example they are kept in sync by using the same address increment
    //and burst sizes. Then the AW and W channels have their transactions measured
    //with threshold counters as part of the user logic, to make sure neither 
    //channel gets too far ahead of each other.

    //Forward movement occurs when the write channel is valid and ready

//写数据通道
/* 写数据通道将会不停地尝试通过接口写数据 
    接收的数据量取决于AXI从设备以及AXI互联的设置,例如,互联是否使能FIFO等
    注意,写数据通道和和写地址通道没有明确的时序关系,写通道有自己的 throttling flag,和写地址通道隔离,
    通道之间的同步必须由用户决定。
    最简单,也是性能最低的情况是只发出一个地址写和写数据突发一次。
    在本例子中,地址和数据通过使用相同的地址增量和相同的突发尺寸保持同步
    然后,AW和W通道使用阈值计数器作为用户逻辑的一部分来度量它们的事务,以确保任何通道都不会彼此超前太远。
    当写通道有效且准备就绪时发生向前移动。
*/
/*译者注:该模块主要功能是按照协议内容对axi_wvalid进行赋值*/
      assign wnext = M_AXI_WREADY & axi_wvalid;   //当一次传输完成后,wnext置位                                 
                                                                                        
    // 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   
/* 该模块主要控制wlast,指示突发传输完成 */                   
      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 when write_index is b1111                           
        // else if (&(write_index[C_TRANSACTIONS_NUM-1:1])&& ~write_index[0] && wnext)  
        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                                                                           
        // Deassrt axi_wlast when the last write data has been                          
        // accepted by the slave with a valid response                                  
        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                                                                               
                                                                                        
                                                                                        
    /* Burst length counter. Uses extra counter register bit to indicate terminal       
     count to reduce decode logic */
    /*译者注:该部分主要对write_index赋值,突发传输数据个数计数器*/                                                   
      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  */
    /*译者注:该模块功能为写数据产生,数据内容 就是从0开始增加的计数值,修改该模块可以操作写入的数据*/        
      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
    //----------------------------

    //The write response channel provides feedback that the write has committed
    //to memory. BREADY will occur when all of the data and the write address
    //has arrived and been accepted by the slave.

    //The write issuance (number of outstanding write addresses) is started by 
    //the Address Write transfer, and is completed by a BREADY/BRESP.

    //While negating BREADY will eventually throttle the AWREADY signal, 
    //it is best not to throttle the whole data channel this way.

    //The BRESP bit [1] is used indicate any errors from the interconnect or
    //slave for the entire write burst. This example will capture the error 
    //into the ERROR output. 

    /* 写响应通道
        写响应通道提供来自从机的写反馈。BREADY信号将会在从机接收到所有的地址和数据之后有效。
        写发送(未完成的写地址数量)由地址写传输启动,并由一个BREADY/BRESP完成。
    */

      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]; 


    //----------------------------
    //Read Address Channel
    //----------------------------

    //The Read Address Channel (AW) provides a similar function to the
    //Write Address channel- to provide the tranfer qualifiers for the burst.

    //In this example, the read address increments in the same
    //manner as the write 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  
    //ARREADY后的下一个地址表示之前的地址接受 ,修改该模块可以操作读取数据的地址
      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                                                                   
                                                                            
                                                                            
    /*                                                                      
     The Read Data channel returns the results of the read request          
     读数据通道返回读请求的结果                                                                       
     In this example the data checker is always able to accept              
     more data, so no need to throttle the RREADY signal
    这个例子中,数据检查器总是能够接收更多的数据,所以没有必要抑制RREADY信号                 
     */                                                                     
      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    
        //当  M_AXI_RVALID 被从机置位时,master使用axi_rready接受/确认rdata/rresp 
        // 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                                            
                                                                            
    //Check received read data against data generator 
    //将接收到的数据和生成的数据比较    ,修改该模块,可以保存读出的数据  (M_AXI_RDATA)                
      always @(posedge M_AXI_ACLK)                                          
      begin                                                                 
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                   
          begin                                                             
            read_mismatch <= 1'b0;                                          
          end                                                               
        //Only check data when RVALID is active 
        //只有当RVALID有效时检查数据                            
        else if (rnext && (M_AXI_RDATA != expected_rdata))                  
          begin                                                             
            read_mismatch <= 1'b1;                                          
          end                                                               
        else                                                                
          read_mismatch <= 1'b0;                                            
      end                                                                 
  
                                                                            
    //Flag any read response errors   
    //标记任何读响应错误                                      
      assign read_resp_error = axi_rready & M_AXI_RVALID & M_AXI_RRESP[1];  


    //----------------------------------------
    //Example design read check data generator
    //-----------------------------------------
    //示例设计了一个读取检查数据生成器
    //Generate expected read data to check against actual read data
    //生成预期的读数据,以对照实际的读数据进行检查

      always @(posedge M_AXI_ACLK)                     
      begin                                                  
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)// || M_AXI_RLAST)             
            expected_rdata <= 'b1;                            
        else if (M_AXI_RVALID && axi_rready)                  
            expected_rdata <= expected_rdata + 1;             
        else                                                  
            expected_rdata <= expected_rdata;                 
      end                                                    


    //----------------------------------
    //Example design error register
    //----------------------------------
    //实例设计了一个错误寄存器,注册并保存任何数据不匹配或读写接口错误
    //Register and hold any data mismatches, or read/write interface errors 

      always @(posedge M_AXI_ACLK)                                 
      begin                                                              
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                          
          begin                                                          
            error_reg <= 1'b0;                                           
          end                                                            
        else if (read_mismatch || write_resp_error || read_resp_error)   //不匹配错误,写响应错误,读响应错误
          begin                                                          
            error_reg <= 1'b1;                                           
          end                                                            
        else                                                             
          error_reg <= error_reg;                                        
      end                                                                


    //--------------------------------
    //Example design throttling
    //--------------------------------

    // For maximum port throughput, this user example code will try to allow
    // each channel to run as independently and as quickly as possible.

    // However, there are times when the flow of data needs to be throtted by
    // the user application. This example application requires that data is
    // not read before it is written and that the write channels do not
    // advance beyond an arbitrary threshold (say to prevent an 
    // overrun of the current read address by the write address).

    // From AXI4 Specification, 13.13.1: "If a master requires ordering between 
    // read and write transactions, it must ensure that a response is received 
    // for the previous transaction before issuing the next transaction."

    // This example accomplishes this user application throttling through:
    // -Reads wait for writes to fully complete
    // -Address writes wait when not read + issued transaction counts pass 
    // a parameterized threshold
    // -Writes wait when a not read + active data burst count pass 
    // a parameterized threshold

     // write_burst_counter counter keeps track with the number of burst transaction initiated            
     // against the number of burst transactions the master needs to initiate                                   
      always @(posedge M_AXI_ACLK)                                                                              
      begin                                                                                                     
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                                                                                 
          begin                                                                                                 
            write_burst_counter <= 'b0;                                                                         
          end                                                                                                   
        else if (M_AXI_AWREADY && axi_awvalid)                                                                  
          begin                                                                                                 
            if (write_burst_counter[C_NO_BURSTS_REQ] == 1'b0)                                                   
              begin                                                                                             
                write_burst_counter <= write_burst_counter + 1'b1;                                              
                //write_burst_counter[C_NO_BURSTS_REQ] <= 1'b1;                                                 
              end                                                                                               
          end                                                                                                   
        else                                                                                                    
          write_burst_counter <= write_burst_counter;                                                           
      end                                                                                                       
                                                                                                                
     // read_burst_counter counter keeps track with the number of burst transaction initiated                   
     // against the number of burst transactions the master needs to initiate                                   
      always @(posedge M_AXI_ACLK)                                                                              
      begin                                                                                                     
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                                                 
          begin                                                                                                 
            read_burst_counter <= 'b0;                                                                          
          end                                                                                                   
        else if (M_AXI_ARREADY && axi_arvalid)                                                                  
          begin                                                                                                 
            if (read_burst_counter[C_NO_BURSTS_REQ] == 1'b0)                                                    
              begin                                                                                             
                read_burst_counter <= read_burst_counter + 1'b1;                                                
                //read_burst_counter[C_NO_BURSTS_REQ] <= 1'b1;                                                  
              end                                                                                               
          end                                                                                                   
        else                                                                                                    
          read_burst_counter <= read_burst_counter;                                                             
      end                                                                                                       
                                                                                                                
                                                                                                                
      //implement master command interface state machine                                                        
      //实现一个状态机,在读写验证之间切换状态

                                                                                                        
      always @ ( posedge M_AXI_ACLK)                                                                            
      begin                                                                                                     
        if (M_AXI_ARESETN == 1'b0 )                                                                             
          begin                                                                                                 
            // reset condition                                                                                  
            // All the signals are assigned default values under reset condition                                
            mst_exec_state      <= IDLE;                                                                
            start_single_burst_write <= 1'b0;                                                                   
            start_single_burst_read  <= 1'b0;                                                                   
            compare_done      <= 1'b0;                                                                          
            ERROR <= 1'b0;   
          end                                                                                                   
        else                                                                                                    
          begin                                                                                                 
                                                                                                                
            // state transition                                                                                 
            case (mst_exec_state)                                                                               
                                                                                                                
              IDLE:                                                                                     
                // This state is responsible to wait for user defined C_M_START_COUNT                           
                // number of clock cycles.
                //该状态负责等待用户定义 C_M_START_COUNT的时钟周期数                                                                    
                if ( init_txn_pulse == 1'b1)   //初始化信号有效时                                                   
                  begin                                                                                         
                    mst_exec_state  <= INIT_WRITE;                                                              
                    ERROR <= 1'b0;
                    compare_done <= 1'b0;
                  end                                                                                           
                else                                                                                            
                  begin                                                                                         
                    mst_exec_state  <= IDLE;                                                            
                  end                                                                                           
                                                                                                                
              INIT_WRITE:                                                                                       
                // This state is responsible to issue start_single_write pulse to                               
                // initiate a write transaction. Write transactions will be                                     
                // issued until burst_write_active signal is asserted.                                          
                // write controller     
                //该状态负责发送写起始信号,初始化写操作。当 burst_write_active signal 被置位后写操作将启动。                                                                      
                if (writes_done) //写操作完了之后,跳转到读状态                                                                               
                  begin                                                                                         
                    mst_exec_state <= INIT_READ;//                                                              
                  end                                                                                           
                else                                                                                            
                  begin                                                                                         
                    mst_exec_state  <= INIT_WRITE; //否则等待                                                              
                                                                                                                
                    if (~axi_awvalid && ~start_single_burst_write && ~burst_write_active)                       
                      begin                                                                                     
                        start_single_burst_write <= 1'b1;                                                       
                      end                                                                                       
                    else                                                                                        
                      begin                                                                                     
                        start_single_burst_write <= 1'b0; //Negate to generate a pulse                          
                      end                                                                                       
                  end                                                                                           
                                                                                                                
              INIT_READ:                                                                                        
                // This state is responsible to issue start_single_read pulse to                                
                // initiate a read transaction. Read transactions will be                                       
                // issued until burst_read_active signal is asserted.                                           
                // read controller   
                //该状态负责发送 start_single_read 脉冲来初始化读操作。当burst_read_active signal  被置位后读操作开始。                                                             
                if (reads_done)                                                                                 
                  begin                                                                                         
                    mst_exec_state <= INIT_COMPARE;                                                             
                  end                                                                                           
                else                                                                                            
                  begin                                                                                         
                    mst_exec_state  <= INIT_READ;                                                               
                                                                                                                
                    if (~axi_arvalid && ~burst_read_active && ~start_single_burst_read)                         
                      begin                                                                                     
                        start_single_burst_read <= 1'b1;                                                        
                      end                                                                                       
                   else                                                                                         
                     begin                                                                                      
                       start_single_burst_read <= 1'b0; //Negate to generate a pulse                            
                     end                                                                                        
                  end                                                                                           
                                                                                                                
              INIT_COMPARE:                                                                                     
                // This state is responsible to issue the state of comparison                                   
                // of written data with the read data. If no error flags are set,                               
                // compare_done signal will be asseted to indicate success.                                     
                //if (~error_reg)  
                //该状态负责发送写入的数据和读出的数据的比较结果,如果没有错误 compare_done 信号将会被置为用来指示传输成功。                                                                            
                begin                                                                                           
                  ERROR <= error_reg;
                  mst_exec_state <= IDLE;                                                               
                  compare_done <= 1'b1;                                                                         
                end                                                                                             
              default :                                                                                         
                begin                                                                                           
                  mst_exec_state  <= IDLE;                                                              
                end                                                                                             
            endcase                                                                                             
          end                                                                                                   
      end //MASTER_EXECUTION_PROC                                                                               
                                                                                                                
       
        //下面这几个触发器,主要功能就是对前面提到的 burst_write_active,burst_read_active和writes_done reads_done等信号进行一个控制
        
                                                                                                         
      // burst_write_active signal is asserted when there is a burst write transaction                          
      // is initiated by the assertion of start_single_burst_write. burst_write_active                          
      // signal remains asserted until the burst write is accepted by the slave  
    //                        
      always @(posedge M_AXI_ACLK)                                                                              
      begin                                                                                                     
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                                                 
          burst_write_active <= 1'b0;                                                                           
                                                                                                                
        //The burst_write_active is asserted when a write burst transaction is initiated                        
        else if (start_single_burst_write)                                                                      
          burst_write_active <= 1'b1;                                                                           
        else if (M_AXI_BVALID && axi_bready)                                                                    
          burst_write_active <= 0;                                                                              
      end                                                                                                       
                                                                                                                
     // Check for last write completion.                                                                        
                                                                                                                
     // This logic is to qualify the last write count with the final write                                      
     // response. This demonstrates how to confirm that a write has been                                        
     // committed.                                                                                              
                                                                                                                
      always @(posedge M_AXI_ACLK)                                                                              
      begin                                                                                                     
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                                                 
          writes_done <= 1'b0;                                                                                  
                                                                                                                
        //The writes_done should be associated with a bready response                                           
        //else if (M_AXI_BVALID && axi_bready && (write_burst_counter == {(C_NO_BURSTS_REQ-1){1}}) && axi_wlast)
        else if (M_AXI_BVALID && (write_burst_counter[C_NO_BURSTS_REQ]) && axi_bready)                          
          writes_done <= 1'b1;                                                                                  
        else                                                                                                    
          writes_done <= writes_done;                                                                           
        end                                                                                                     
                                                                                                                
      // burst_read_active signal is asserted when there is a burst write transaction                           
      // is initiated by the assertion of start_single_burst_write. start_single_burst_read                     
      // signal remains asserted until the burst read is accepted by the master                                 
      always @(posedge M_AXI_ACLK)                                                                              
      begin                                                                                                     
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                                                 
          burst_read_active <= 1'b0;                                                                            
                                                                                                                
        //The burst_write_active is asserted when a write burst transaction is initiated                        
        else if (start_single_burst_read)                                                                       
          burst_read_active <= 1'b1;                                                                            
        else if (M_AXI_RVALID && axi_rready && M_AXI_RLAST)                                                     
          burst_read_active <= 0;                                                                               
        end                                                                                                     
                                                                                                                
                                                                                                                
     // Check for last read completion.                                                                         
                                                                                                                
     // This logic is to qualify the last read count with the final read                                        
     // response. This demonstrates how to confirm that a read has been                                         
     // committed.                                                                                              
                                                                                                                
      always @(posedge M_AXI_ACLK)                                                                              
      begin                                                                                                     
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)                                                                                 
          reads_done <= 1'b0;                                                                                   
                                                                                                                
        //The reads_done should be associated with a rready response                                            
        //else if (M_AXI_BVALID && axi_bready && (write_burst_counter == {(C_NO_BURSTS_REQ-1){1}}) && axi_wlast)
        else if (M_AXI_RVALID && axi_rready && (read_index == C_M_AXI_BURST_LEN-1) && (read_burst_counter[C_NO_BURSTS_REQ]))
          reads_done <= 1'b1;                                                                                   
        else                                                                                                    
          reads_done <= reads_done;                                                                             
        end                                                                                                     

    // Add user logic here

    // User logic ends

    endmodule文章来源地址https://www.toymoban.com/news/detail-678414.html

到了这里,关于ZYNQ之路--Xilinx AXI-Full-Master实例代码翻译的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 带你快速入门AXI4总线--AXI4-Full篇(1)----AXI4-Full总线

    目录 1、什么是AXI4-Full? 2、通道(Channel) 2.1、AXI 读取传输事务 2.2、AXI 写入传输事务

    2024年02月01日
    浏览(16)
  • 详解AXI4-Full接口(1)--什么是AXI4-Full接口?

    目录 1、什么是AXI4-Full? 2、通道(Channel) 2.1、AXI 读取传输事务 2.2、AXI 写入传输事务

    2024年02月09日
    浏览(23)
  • Zynq AXI_HP 接口详解

    Zynq AXI_HP 接口详解 如果你是一名 FPGA 开发者,那么你一定对 Zynq 这个硬件平台不会陌生。Zynq 平台以其强大的功能和高性能而受到广泛关注。其中,AXI_HP 接口是 Zynq 平台中非常重要的一部分,它是 High Performance AXI Master 和 Slave 的缩写,具有高速数据传输和 DMA(Direct Memory Ac

    2024年02月08日
    浏览(14)
  • ZYNQ PS使用axi uartlite进行串口收发

    由于使用的ZYNQ PS部分只有两个串口,其中一个还当成了控制台用,串口不够用,于是使用PL的逻辑部分并利用IP核:AXI UARTLITE 为PS增加串口数量,并添加了AXI TIMER。 Vivado和Vitis为2020,PS为裸机使用。 包含以下内容: 1、Vivado的配置 2、axi uartlite代码 3、axi timer代码 4、利用IP核:

    2024年04月12日
    浏览(14)
  • ZYNQ AXI-DMA Linux Cache 一致

    平台为 ZYNQ MPSOC 项目使用到AXI-DMA ,ADC模块传输数据到DDR,应用层进行数据的读取。在此做些记录 用到了AXI-Stream , IP核用的 米联客的ui_axisbufw,可以把流数据转为AXI-Stream 接口 比较重要的参考链接 1.UltraScale+MPSoC+Cache+Coherency https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842098/Zynq+

    2024年02月03日
    浏览(14)
  • Xilinx ZYNQ 7000学习笔记三(小结)

    ZYNQ 7000的启动模式由外部引脚决定的,5个模式引脚MIO[6:2]用于配置NAND flash、并行NOR flash、Serial NOR (Quad-SPI)、SD flash以及JTAG 一共5种启动模式。具体而言就是复位时,zynq-7000 SOC对下述引脚进行连续3个时钟周期采样。复位采样MIO[6:2]并将采样的模式值保存到系统级控制寄存器SL

    2024年02月09日
    浏览(8)
  • 基于xilinx的axi-fifo的应用

    作为一个有一定工作经验(划水好多年)的FPGA工程师,很多模块都已经学习过或者使用过,但是如果让我重新实现,感觉又是一脸懵。因此,这是我发文档的原因。对于自己来说,这是一个总结归纳的过程,对读者,可能是一次解惑。 后期,将会逐渐分享DDR/ETH/SERDES/PCIe/SP

    2024年02月09日
    浏览(18)
  • xilinx zynq7系列加载器无法连接的原因&测试xilinx Zynq7开发板的加载器和芯片是否正常的快速方法

    1.硬件部分 首先将加载器与PC机和开发板的连接好 pc端直接插在usb接口上即可 1.1开发板侧,连接如下图 1.2连接Jtag 绿色写的是JTAG的标识,连接线有凹槽的方向朝内,红色圈出部分 这些加载线在买开发板的时候都是有附带的,如果没有的话,去某宝上买也很方便。 2.软件测试

    2024年02月12日
    浏览(15)
  • ZYNQ AXI_DMA_UDP以太网传输(二)问题记录

    上一篇文章只是简单的记录一下调试成功的代码 但调试成功这个过程很痛苦,踩了很多坑,特此记录,留眼以后查看 参考博客 xilinx dma调试笔记 ZYNQ AXI DMA调试细节 在调试过程中出现这类问题基本上都是这一句代码出了问题: 再往里面跳可以看见这样一个函数,在正点原子提

    2024年03月14日
    浏览(26)
  • Xilinx ZYNQ 7000学习笔记一(复位和启动)

    参考文献:Zynq-7000 SoC Technical Reference Manual (UG585)-ch26 Reset System zynq7000复位信号源包括硬件复位、看门狗定时器、JTAG控制器复位信号和软件复位信号。其中,硬件复位引脚由上电复位信号PS_POR_B和系统复位信号PS_SRST_B驱动。在PS中,有3个看门狗定时器可用来产生复位信号;JTA

    2024年02月06日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包