【【萌新的SOC学习之AXI IP代码解释】】

博客聚焦于萌新的SOC学习,对AXI IP代码进行解释,涉及axi4_rw_test_v1_0.v和axi4_rw_test_v1_0_M_AXI.v两个文件,属于信息技术领域的学习内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

萌新的SOC学习之AXI IP代码解释

axi4_rw_test_v1_0 .v

`timescale 1 ns / 1 ps
module axi4_rw_test_v1_0 #
(
    // Users to add parameters here

    // User parameters ends
    // Do not modify the parameters beyond this line


    // Parameters of Axi Master Bus Interface M_AXI
    //在这里定义参数的好处是 我们添加IP核的时候 可以在vivado的框图里面对参数的默认值进行修改
    parameter  C_M_AXI_TARGET_SLAVE_BASE_ADDR    = 32'h40000000,   //基地址  
    parameter integer C_M_AXI_BURST_LEN    = 16,   //设置突发长度
    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
)
(
    // Users to add ports here

    // User ports ends
    // Do not modify the ports beyond this line


    // Ports of Axi Master Bus Interface M_AXI
    input wire  m_axi_init_axi_txn,      //开始触发信号  只有检测到上升沿 才会开始读写信号 
    output wire  m_axi_txn_done,      //比较完成操作信号  在读写操作完成之后内部会进行比较
    output wire  m_axi_error,        //比较的过程中 或响应信号出错 都会拉高指示当前错误 
    //这里只有三个信号要连接到外部的
    input wire  m_axi_aclk,
    input wire  m_axi_aresetn,
    output wire [C_M_AXI_ID_WIDTH-1 : 0] m_axi_awid,
    output wire [C_M_AXI_ADDR_WIDTH-1 : 0] m_axi_awaddr,
    output wire [7 : 0] m_axi_awlen,
    output wire [2 : 0] m_axi_awsize,
    output wire [1 : 0] m_axi_awburst,
    output wire  m_axi_awlock,
    output wire [3 : 0] m_axi_awcache,
    output wire [2 : 0] m_axi_awprot,
    output wire [3 : 0] m_axi_awqos,
    output wire [C_M_AXI_AWUSER_WIDTH-1 : 0] m_axi_awuser,
    output wire  m_axi_awvalid,
    input wire  m_axi_awready,         
    output wire [C_M_AXI_DATA_WIDTH-1 : 0] m_axi_wdata,
    output wire [C_M_AXI_DATA_WIDTH/8-1 : 0] m_axi_wstrb,
    output wire  m_axi_wlast,
    output wire [C_M_AXI_WUSER_WIDTH-1 : 0] m_axi_wuser,
    output wire  m_axi_wvalid,
    input wire  m_axi_wready,
    input wire [C_M_AXI_ID_WIDTH-1 : 0] m_axi_bid,
    input wire [1 : 0] m_axi_bresp,
    input wire [C_M_AXI_BUSER_WIDTH-1 : 0] m_axi_buser,
    input wire  m_axi_bvalid,
    output wire  m_axi_bready,
    output wire [C_M_AXI_ID_WIDTH-1 : 0] m_axi_arid,
    output wire [C_M_AXI_ADDR_WIDTH-1 : 0] m_axi_araddr,
    output wire [7 : 0] m_axi_arlen,
    output wire [2 : 0] m_axi_arsize,
    output wire [1 : 0] m_axi_arburst,
    output wire  m_axi_arlock,
    output wire [3 : 0] m_axi_arcache,
    output wire [2 : 0] m_axi_arprot,
    output wire [3 : 0] m_axi_arqos,
    output wire [C_M_AXI_ARUSER_WIDTH-1 : 0] m_axi_aruser,
    output wire  m_axi_arvalid,
    input wire  m_axi_arready,
    input wire [C_M_AXI_ID_WIDTH-1 : 0] m_axi_rid,
    input wire [C_M_AXI_DATA_WIDTH-1 : 0] m_axi_rdata,
    input wire [1 : 0] m_axi_rresp,
    input wire  m_axi_rlast,
    input wire [C_M_AXI_RUSER_WIDTH-1 : 0] m_axi_ruser,
    input wire  m_axi_rvalid,
    output wire  m_axi_rready
);

// Instantiation of Axi Bus Interface M_AXI
axi4_rw_test_v1_0_M_AXI # (
.C_M_TARGET_SLAVE_BASE_ADDR(C_M_AXI_TARGET_SLAVE_BASE_ADDR),
.C_M_AXI_BURST_LEN(C_M_AXI_BURST_LEN),
.C_M_AXI_ID_WIDTH(C_M_AXI_ID_WIDTH),
.C_M_AXI_ADDR_WIDTH(C_M_AXI_ADDR_WIDTH),
.C_M_AXI_DATA_WIDTH(C_M_AXI_DATA_WIDTH),
.C_M_AXI_AWUSER_WIDTH(C_M_AXI_AWUSER_WIDTH),
.C_M_AXI_ARUSER_WIDTH(C_M_AXI_ARUSER_WIDTH),
.C_M_AXI_WUSER_WIDTH(C_M_AXI_WUSER_WIDTH),
.C_M_AXI_RUSER_WIDTH(C_M_AXI_RUSER_WIDTH),
.C_M_AXI_BUSER_WIDTH(C_M_AXI_BUSER_WIDTH)
) axi4_rw_test_v1_0_M_AXI_inst (
.INIT_AXI_TXN(m_axi_init_axi_txn),
.TXN_DONE(m_axi_txn_done),
.ERROR(m_axi_error),
.M_AXI_ACLK(m_axi_aclk),
.M_AXI_ARESETN(m_axi_aresetn),
.M_AXI_AWID(m_axi_awid),
.M_AXI_AWADDR(m_axi_awaddr),
.M_AXI_AWLEN(m_axi_awlen),
.M_AXI_AWSIZE(m_axi_awsize),
.M_AXI_AWBURST(m_axi_awburst),
.M_AXI_AWLOCK(m_axi_awlock),
.M_AXI_AWCACHE(m_axi_awcache),
.M_AXI_AWPROT(m_axi_awprot),
.M_AXI_AWQOS(m_axi_awqos),
.M_AXI_AWUSER(m_axi_awuser),
.M_AXI_AWVALID(m_axi_awvalid),
.M_AXI_AWREADY(m_axi_awready),
.M_AXI_WDATA(m_axi_wdata),
.M_AXI_WSTRB(m_axi_wstrb),
.M_AXI_WLAST(m_axi_wlast),
.M_AXI_WUSER(m_axi_wuser),
.M_AXI_WVALID(m_axi_wvalid),
.M_AXI_WREADY(m_axi_wready),
.M_AXI_BID(m_axi_bid),
.M_AXI_BRESP(m_axi_bresp),
.M_AXI_BUSER(m_axi_buser),
.M_AXI_BVALID(m_axi_bvalid),
.M_AXI_BREADY(m_axi_bready),
.M_AXI_ARID(m_axi_arid),
.M_AXI_ARADDR(m_axi_araddr),
.M_AXI_ARLEN(m_axi_arlen),
.M_AXI_ARSIZE(m_axi_arsize),
.M_AXI_ARBURST(m_axi_arburst),
.M_AXI_ARLOCK(m_axi_arlock),
.M_AXI_ARCACHE(m_axi_arcache),
.M_AXI_ARPROT(m_axi_arprot),
.M_AXI_ARQOS(m_axi_arqos),
.M_AXI_ARUSER(m_axi_aruser),
.M_AXI_ARVALID(m_axi_arvalid),
.M_AXI_ARREADY(m_axi_arready),
.M_AXI_RID(m_axi_rid),
.M_AXI_RDATA(m_axi_rdata),
.M_AXI_RRESP(m_axi_rresp),
.M_AXI_RLAST(m_axi_rlast),
.M_AXI_RUSER(m_axi_ruser),
.M_AXI_RVALID(m_axi_rvalid),
.M_AXI_RREADY(m_axi_rready)
);
// Add user logic here

// User logic ends

endmodule

axi4_rw_test_v1_0_M_AXI .v

`timescale 1 ns / 1 ps

    module axi4_rw_test_v1_0_M_AXI #
    (
        // Users to add parameters here

        // User parameters ends
        // Do not modify the parameters beyond this line

        // Base address of targeted slave
        parameter  C_M_TARGET_SLAVE_BASE_ADDR    = 32'h40000000,
        // Burst Length. Supports 1, 2, 4, 8, 16, 32, 64, 128, 256 burst lengths
        parameter integer C_M_AXI_BURST_LEN    = 16,
        // Thread ID Width
        parameter integer C_M_AXI_ID_WIDTH    = 1,
        // Width of Address Bus
        parameter integer C_M_AXI_ADDR_WIDTH    = 32,
        // Width of Data Bus
        parameter integer C_M_AXI_DATA_WIDTH    = 32,
        // Width of User Write Address Bus
        parameter integer C_M_AXI_AWUSER_WIDTH    = 0,
        // Width of User Read Address Bus
        parameter integer C_M_AXI_ARUSER_WIDTH    = 0,
        // Width of User Write Data Bus
        parameter integer C_M_AXI_WUSER_WIDTH    = 0,
        // Width of User Read Data Bus
        parameter integer C_M_AXI_RUSER_WIDTH    = 0,
        // Width of User Response Bus
        parameter integer C_M_AXI_BUSER_WIDTH    = 0
    )
    //前面这部分同样是定义参数  
    (
        // Users to add ports here

        // User ports ends
        // Do not modify the ports beyond this line

        // Initiate AXI transactions
        input wire  INIT_AXI_TXN,   //我们可以 用以连接按键 但是注意这个信号是高电平有效 
        // Asserts when transaction is complete
        output wire  TXN_DONE,
        // Asserts when ERROR is detected
        output reg  ERROR,
        //前三个是用户的IO 可以连接到我们的IO引脚上去 
        //下面是主端口信号 
        // Global Clock Signal.
        input wire  M_AXI_ACLK,
        // Global Reset Singal. This Signal is Active Low
        input wire  M_AXI_ARESETN,
        // Master Interface Write Address ID
        output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_AWID,
        // Master Interface Write Address
        output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
        // Burst length. The burst length gives the exact number of transfers in a burst
        output wire [7 : 0] M_AXI_AWLEN,
        // Burst size. This signal indicates the size of each transfer in the burst
        output wire [2 : 0] M_AXI_AWSIZE,
        // Burst type. 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,
        // Memory type. This signal indicates how transactions
    // are required to progress through a system.
        output wire [3 : 0] M_AXI_AWCACHE,
        // 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,
        // Quality of Service, QoS identifier sent for each write transaction.
        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,
        // Write address valid. This signal indicates that
    // the channel is 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.
        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 last. 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,
        // 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.
        input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_BID,
        // Write response. 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,
        // 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.
        output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_ARID,
        // Read address. This signal indicates the initial
    // address of a read burst transaction.
        output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
        // Burst length. The burst length gives the exact number of transfers in a burst
        output wire [7 : 0] M_AXI_ARLEN,
        // Burst size. This signal indicates the size of each transfer in the burst
        output wire [2 : 0] M_AXI_ARSIZE,
        // Burst type. 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,
        // Lock type. Provides additional information about the
    // atomic characteristics of the transfer.
        output wire  M_AXI_ARLOCK,
        // Memory type. This signal indicates how transactions
    // are required to progress through a system.
        output wire [3 : 0] M_AXI_ARCACHE,
        // 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,
        // Quality of Service, 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,
        // Write 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,
        // Read ID tag. 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,
        // Master Read Data
        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 last. 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,
        // 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
    );


    // function called clogb2 that returns an integer which has the
    //value of the ceiling of the log base 2

      // 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.
     localparam integer C_TRANSACTIONS_NUM = clogb2(C_M_AXI_BURST_LEN-1);    //4 

    // Burst length for transactions, in C_M_AXI_DATA_WIDTHs.
    // Non-2^n lengths will eventually cause bursts across 4K address boundaries.
     localparam integer C_MASTER_LENGTH    = 12;
    // total number of burst transfers is master length divided by burst length and burst size
     localparam integer C_NO_BURSTS_REQ = C_MASTER_LENGTH-clogb2((C_M_AXI_BURST_LEN*C_M_AXI_DATA_WIDTH/8)-1); //6
    // Example State machine to initialize counter, initialize write transactions, 
    // initialize read transactions and comparison of read data with the 
    // written data words.  
    //用来放在写突发和读突发的位宽上 
    
    //这介绍  了 状态机的状态 配置  
    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_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
    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.
    reg [C_NO_BURSTS_REQ : 0]     write_burst_counter;   //[6:0]  
    reg [C_NO_BURSTS_REQ : 0]     read_burst_counter;    //[6:0]  
    //看上去很复杂 其实用计算的方法给出位宽 后续我们只需要修改指定的 参数就可以了  
    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)
    assign M_AXI_AWID    = 'b0;   //写地址的ID 
    //The AXI address is a concatenation of the target base address + active offset range
    assign M_AXI_AWADDR    = C_M_TARGET_SLAVE_BASE_ADDR + axi_awaddr; //地址   =  基地址 + 一个变量 
    //所以我们在后面的观察中 主要观察的是变量 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
    assign M_AXI_AWSIZE    = clogb2((C_M_AXI_DATA_WIDTH/8)-1);  //2'b10  字节是4byte
    
    
    //INCR burst type is usually used, except for keyhole bursts
    assign M_AXI_AWBURST    = 2'b01;  // 设置 突发类型 01 设置的是自增的类型
    
    assign M_AXI_AWLOCK    = 1'b0;       //所得类型为0  固定值  
    
    //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_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}};   //屏闪信号 4'b1111 表示四个字节都是有效的 
    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
    assign TXN_DONE    = compare_done;
    //Burst size in bytes
    assign burst_size_bytes    = C_M_AXI_BURST_LEN * C_M_AXI_DATA_WIDTH/8;  //突发大小是多少字节 64字节 
    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     


    //--------------------
    //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指向下一个地址。

// 这部分是写地址vaild信号的赋值的 

      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;      // 有效信号为0 并且突发写信号为1 时 拉高这个有效信号                                        
          end                                                              
        /* Once asserted, VALIDs cannot be deasserted, so axi_awvalid      
        must wait until transaction is accepted */                         
        else if (M_AXI_AWREADY && axi_awvalid)    //当握手 时 拉低信号                        
          begin                                                            
            axi_awvalid <= 1'b0;                                           
          end                                                              
        else                                                               
          axi_awvalid <= axi_awvalid;                                      
        end                                                                
         //我们会发现 一开始这个信号是0  经历了一个脉冲信号被拉高    拉低的条件是握手成功                                                              
           


//对写地址通道的 地址进行赋值            
    // Next address after AWREADY indicates previous address acceptance    
      always @(posedge M_AXI_ACLK)                                         
      begin                                                                
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)    //复位 或者信号拉高的时候清零                                          
          begin                                                            
            axi_awaddr <= 'b0;                                             
          end                                                              
        else if (M_AXI_AWREADY && axi_awvalid)         //当他们成功进行了一次握手之后 地址开始进行累加                       
          begin                                                            
            axi_awaddr <= axi_awaddr + burst_size_bytes;  //这个值是我们在前面计算得到是64字节 
// 突发长度是16 突发 side是 4 乘起来 就是 64字节              
          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



//这部分是写数据通道变量的赋值 了 
      assign wnext = M_AXI_WREADY & axi_wvalid;   //  这将两个握手信号统一在一起了  
      
                                                                                        
    // 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_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               //握手并且突发长度满足要求    或     突发长度=1  满足两者之一的条件                                                          
            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)) //当成功握手 并且不等于突发长度减一的时候加1 
        //index其实就是统计写了多少个数据的 
          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  */   
//写数据的产生      
      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信号就好了 
      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)    //检测到bvalid  和自己为 0 就 拉高                             
          begin                                                             
            axi_bready <= 1'b1;                                             
          end                                                               
        // deassert after one clock cycle                                   
        else if (axi_bready)          //拉高之后 就给0 相当于只拉高了一个时钟周期                                          
          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]; 
//对写响应信号的判断 
//M_AXI_BRESP[1]  这是写响应信号返回的响应信号  这里是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  
      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                    
     */                                                                     
      always @(posedge M_AXI_ACLK)                                          
      begin                                                                 
        if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )                  
          begin                                                             
            axi_rready <= 1'b0;                                             
          end                                                               
        // accept/acknowledge rdata/rresp with axi_rready by the master     
        // when M_AXI_RVALID is asserted by slave                           
        else if (M_AXI_RVALID)                       
          begin                                      
             if (M_AXI_RLAST && axi_rready)          
              begin                                  
                axi_rready <= 1'b0;                  
              end                                    
             else                                    
               begin                                 
                 axi_rready <= 1'b1;                 
               end                                   
          end                                        
        // retain the previous value                 
      end                                            
                                                                            
    //Check received read data against data generator 
//读错误信号     
      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                             
        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;            //复位之后给 了 IDIE状态                                                        
            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.                                                                      
                if ( init_txn_pulse == 1'b1)         //输入为1 到write                                                
                  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                                                                             
                if (writes_done)                                                                                
                  begin                                                                                         
                    mst_exec_state <= INIT_READ;//                                                              
                  end                                                                                           
                else     //在这个 write还没写完之前 进行下面的 指令执行                                                                                         
                  begin                                                                                         
                    mst_exec_state  <= INIT_WRITE;                                                              
                           //这个信号其实是一个脉冲信号 
                           // 一直进入这个状态 内     
                          // 在我们写完成之后 我们 会跳出到 read 的状态                            
                    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                                                                              
                if (reads_done)                                                                                 
                  begin                                                                                         
                    mst_exec_state <= INIT_COMPARE;                                                             
                  end                                                                                           
                else                                                                                            
                  begin                                                                                         
                    mst_exec_state  <= INIT_READ;                                                               
                                 //read和 write的  类型差不多  这都是经历 了一轮的脉冲信号                                                                             
                    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)                                                                               
                begin              //比较的状态 下一个状态跳转到了IDLE 并给出相应的结果                                                                                
                  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 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值