Axi3 Master Code

11
9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 1/11 //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ // // AXI Master // // Verilog‐standard: Verilog 2001 //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ // // Structure: // axi3_master // // Last Update: // 2/07/2013 // //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ /* AXI Master Example The purpose of this design is to provide a high‐throughput AXI3 example and AXI throughput demonstration. The example user application performs a simple memory test through continuous burst writes to memory, followed by burst reads. The simple data pattern is checked and any data comparison or interface errors are latched with the example ERROR output. To modify this example for other applications, edit/remove the logic associated with the 'Example' section comments. For clarity, most transfer qualifiers are left as constants, but can be easily added to their associated channels. The latest version of this file can be found in Xilinx Answer 37425 http://www.xilinx.com/support/answers/37425.htm */ `timescale 1ns/1ps //Simple Log2 calculation function `define C_LOG_2(n) (\ (n) <= (1<<0) ? 0 : (n) <= (1<<1) ? 1 :\ (n) <= (1<<2) ? 2 : (n) <= (1<<3) ? 3 :\ (n) <= (1<<4) ? 4 : (n) <= (1<<5) ? 5 :\ (n) <= (1<<6) ? 6 : (n) <= (1<<7) ? 7 :\ (n) <= (1<<8) ? 8 : (n) <= (1<<9) ? 9 :\ (n) <= (1<<10) ? 10 : (n) <= (1<<11) ? 11 :\ (n) <= (1<<12) ? 12 : (n) <= (1<<13) ? 13 :\ (n) <= (1<<14) ? 14 : (n) <= (1<<15) ? 15 :\ (n) <= (1<<16) ? 16 : (n) <= (1<<17) ? 17 :\ (n) <= (1<<18) ? 18 : (n) <= (1<<19) ? 19 :\ (n) <= (1<<20) ? 20 : (n) <= (1<<21) ? 21 :\ (n) <= (1<<22) ? 22 : (n) <= (1<<23) ? 23 :\ (n) <= (1<<24) ? 24 : (n) <= (1<<25) ? 25 :\ (n) <= (1<<26) ? 26 : (n) <= (1<<27) ? 27 :\ (n) <= (1<<28) ? 28 : (n) <= (1<<29) ? 29 :\ (n) <= (1<<30) ? 30 : (n) <= (1<<31) ? 31 : 32) module axi3_master # ( parameter C_M_AXI_PROTOCOL = "AXI3", parameter integer C_M_AXI_THREAD_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 = 1, parameter integer C_M_AXI_ARUSER_WIDTH = 1, parameter integer C_M_AXI_WUSER_WIDTH = 1,

description

AXI

Transcript of Axi3 Master Code

Page 1: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 1/11

//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐//// AXI Master//// Verilog‐standard:  Verilog 2001//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐//// Structure://   axi3_master//// Last Update://   2/07/2013////‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐/* AXI Master Example  The purpose of this design is to provide a high‐throughput AXI3 example  and AXI throughput demonstration.   The example user application performs a simple memory test through continuous burst writes to memory, followed by burst reads.  The simple data pattern is checked and any data comparison or interface errors are latched with the example ERROR output.  To modify this example for other applications, edit/remove the logic associated with the 'Example' section comments. For clarity, most transfer qualifiers are left as constants, but can be easily added to their associated channels.  The latest version of this file can be found in Xilinx Answer 37425 http://www.xilinx.com/support/answers/37425.htm */

`timescale 1ns/1ps

//Simple Log2 calculation function`define C_LOG_2(n) (\(n) <= (1<<0) ? 0 : (n) <= (1<<1) ? 1 :\(n) <= (1<<2) ? 2 : (n) <= (1<<3) ? 3 :\(n) <= (1<<4) ? 4 : (n) <= (1<<5) ? 5 :\(n) <= (1<<6) ? 6 : (n) <= (1<<7) ? 7 :\(n) <= (1<<8) ? 8 : (n) <= (1<<9) ? 9 :\(n) <= (1<<10) ? 10 : (n) <= (1<<11) ? 11 :\(n) <= (1<<12) ? 12 : (n) <= (1<<13) ? 13 :\(n) <= (1<<14) ? 14 : (n) <= (1<<15) ? 15 :\(n) <= (1<<16) ? 16 : (n) <= (1<<17) ? 17 :\(n) <= (1<<18) ? 18 : (n) <= (1<<19) ? 19 :\(n) <= (1<<20) ? 20 : (n) <= (1<<21) ? 21 :\(n) <= (1<<22) ? 22 : (n) <= (1<<23) ? 23 :\(n) <= (1<<24) ? 24 : (n) <= (1<<25) ? 25 :\(n) <= (1<<26) ? 26 : (n) <= (1<<27) ? 27 :\(n) <= (1<<28) ? 28 : (n) <= (1<<29) ? 29 :\(n) <= (1<<30) ? 30 : (n) <= (1<<31) ? 31 : 32)

module axi3_master #  (   parameter C_M_AXI_PROTOCOL = "AXI3",   parameter integer C_M_AXI_THREAD_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 = 1,   parameter integer C_M_AXI_ARUSER_WIDTH = 1,   parameter integer C_M_AXI_WUSER_WIDTH = 1,

Page 2: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 2/11

   parameter integer C_M_AXI_RUSER_WIDTH = 1,   parameter integer C_M_AXI_BUSER_WIDTH = 1,      /* Disabling these parameters will remove any throttling.    The resulting ERROR flag will not be useful */    parameter integer C_M_AXI_SUPPORTS_WRITE = 1,   parameter integer C_M_AXI_SUPPORTS_READ = 1,      /* Max count of written but not yet read bursts.    If the interconnect/slave is able to accept enough    addresses and the read channels are stalled, the    master will issue this many commands ahead of     write responses */   parameter integer C_INTERCONNECT_M_AXI_WRITE_ISSUING = 8,            ////////////////////////////   // Example design parameters   ////////////////////////////      // Base address of targeted slave   parameter C_M_AXI_TARGET = 'h00000000,      // Number of address bits to test before wrapping   parameter integer C_OFFSET_WIDTH = 20,      /* Burst length for transactions, in C_M_AXI_DATA_WIDTHs.    Non‐2^n lengths will eventually cause bursts across 4K    address boundaries.*/   parameter integer C_M_AXI_BURST_LEN = 16   )   (    // System Signals    input wire              ACLK,    input wire              ARESETN,        // Master Interface Write Address    output wire [C_M_AXI_THREAD_ID_WIDTH‐1:0] M_AXI_AWID,    output wire [C_M_AXI_ADDR_WIDTH‐1:0]      M_AXI_AWADDR,    output wire [4‐1:0]           M_AXI_AWLEN,    output wire [3‐1:0]           M_AXI_AWSIZE,    output wire [2‐1:0]           M_AXI_AWBURST,    output wire             M_AXI_AWLOCK,    output wire [4‐1:0]           M_AXI_AWCACHE,    output wire [3‐1:0]           M_AXI_AWPROT,    //output wire [4‐1:0]       M_AXI_AWREGION,   // AXI4 output wire [4‐1: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,        // Master Interface Write Data    output wire [C_M_AXI_THREAD_ID_WIDTH‐1:0] M_AXI_WID,    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,        // Master Interface Write Response    input wire [C_M_AXI_THREAD_ID_WIDTH‐1:0]  M_AXI_BID,    input wire [2‐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,

Page 3: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 3/11

        // Master Interface Read Address    output wire [C_M_AXI_THREAD_ID_WIDTH‐1:0] M_AXI_ARID,    output wire [C_M_AXI_ADDR_WIDTH‐1:0]      M_AXI_ARADDR,    output wire [4‐1:0]           M_AXI_ARLEN,    output wire [3‐1:0]           M_AXI_ARSIZE,    output wire [2‐1:0]           M_AXI_ARBURST,    output wire [2‐1:0]           M_AXI_ARLOCK,    output wire [4‐1:0]           M_AXI_ARCACHE,    output wire [3‐1:0]           M_AXI_ARPROT,    // AXI3 output wire [4‐1:0]      M_AXI_ARREGION,    //output wire [4‐1: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,        // Master Interface Read Data     input wire [C_M_AXI_THREAD_ID_WIDTH‐1:0]  M_AXI_RID,    input wire [C_M_AXI_DATA_WIDTH‐1:0]       M_AXI_RDATA,    input wire [2‐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,

    // Example Design    output wire             ERROR    ); 

      // A fancy terminal counter, using extra bits to reduce decode logic   localparam integer         C_WLEN_COUNT_WIDTH = `C_LOG_2(C_M_AXI_BURST_LEN‐2)+2;   reg [C_WLEN_COUNT_WIDTH‐1:0]      wlen_count; 

   // Local address counters   reg [C_OFFSET_WIDTH‐1:0]       araddr_offset = 'b0;   reg [C_OFFSET_WIDTH‐1:0]       awaddr_offset = 'b0;

   // Example throttling counters   reg [`C_LOG_2(C_INTERCONNECT_M_AXI_WRITE_ISSUING)‐1:0]   unread_writes;   reg [`C_LOG_2(C_INTERCONNECT_M_AXI_WRITE_ISSUING)‐1:0]   aw_issue_count;   reg [`C_LOG_2(C_INTERCONNECT_M_AXI_WRITE_ISSUING)‐1:0]   w_issue_count;

   // Throttling flags   reg             aw_throttle;   reg             w_throttle;   reg             ar_throttle;

   // Example user application signals   reg             read_mismatch;   reg             error_reg;   reg [C_OFFSET_WIDTH‐1:0]       data_gen; //optimized for example design   reg [C_OFFSET_WIDTH‐1:0]       wdata; //optimized for example design     // Interface response error flags   wire            write_resp_error;   wire            read_resp_error; 

   // AXI4 temp signals   reg             awvalid;   wire            wlast;   reg             wvalid;   reg             bready;   reg             arvalid;

Page 4: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 4/11

   reg             rready;      wire            wnext;   ///////////////////I/O Connections///////////////////////////////////// //Write Address (AW)////////////////////

// Single threaded   assign M_AXI_AWID = 'b0;   

// The AXI address is a concatenation of the target base address + active offset rangeassign M_AXI_AWADDR = {C_M_AXI_TARGET[C_M_AXI_ADDR_WIDTH‐1:C_OFFSET_WIDTH],awaddr_offset};

//Burst LENgth is number of transaction beats, minus 1assign 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 usedassign M_AXI_AWSIZE = `C_LOG_2(C_M_AXI_DATA_WIDTH/8);

// INCR burst type is usually used, except for keyhole burstsassign M_AXI_AWBURST = 2'b01;assign M_AXI_AWLOCK = 1'b0;

// Not Allocated, Modifiable and Bufferableassign M_AXI_AWCACHE = 4'b0011;assign M_AXI_AWPROT = 3'h0;assign M_AXI_AWQOS = 4'h0;

//Set User[0] to 1 to allow Zynq coherent ACP transactionsassign M_AXI_AWUSER = 'b1;assign M_AXI_AWVALID = awvalid;

/////////////////Write Data(W)///////////////assign M_AXI_WDATA = {C_M_AXI_TARGET[C_M_AXI_ADDR_WIDTH‐1:C_OFFSET_WIDTH],wdata};

//All bursts are complete and aligned in this exampleassign M_AXI_WID = 'b0;assign M_AXI_WSTRB = {(C_M_AXI_DATA_WIDTH/8){1'b1}};assign M_AXI_WLAST = wlast;assign M_AXI_WUSER = 'b0;assign M_AXI_WVALID = wvalid;

//////////////////////Write Response (B)////////////////////assign M_AXI_BREADY = bready;

/////////////////////Read Address (AR)///////////////////assign M_AXI_ARID = 'b0;assign M_AXI_ARADDR = {C_M_AXI_TARGET[C_M_AXI_ADDR_WIDTH‐1:C_OFFSET_WIDTH],araddr_offset};

//Burst LENgth is number of transaction beats, minus 1assign 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 usedassign M_AXI_ARSIZE = `C_LOG_2(C_M_AXI_DATA_WIDTH/8);

Page 5: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 5/11

// INCR burst type is usually used, except for keyhole burstsassign M_AXI_ARBURST = 2'b01;assign M_AXI_ARLOCK = 1'b0;   // Not Allocated, Modifiable and Bufferableassign M_AXI_ARCACHE = 4'b0011;assign M_AXI_ARPROT = 3'h0;assign M_AXI_ARQOS = 4'h0;

//Set User[0] to 1 to allow Zynq coherent ACP transactionsassign M_AXI_ARUSER = 'b1;assign M_AXI_ARVALID = arvalid;

//////////////////////////////Read and Read Response (R)////////////////////////////assign M_AXI_RREADY = rready;

//////////////////////Example design I/O////////////////////assign ERROR = error_reg;

//////////////////////////////////////////////////Reset logic, workaround for AXI_BRAM CR#582705////////////////////////////////////////////////reg aresetn_r = 1'b0;reg aresetn_r1 = 1'b0;reg aresetn_r2 = 1'b0;reg aresetn_r3 = 1'b0;reg aresetn_r4 = 1'b0;

always @(posedge ACLK)begin   aresetn_r <= ARESETN;   aresetn_r1 <= aresetn_r;   aresetn_r2 <= aresetn_r1;   aresetn_r3 <= aresetn_r2;   aresetn_r4 <= aresetn_r3;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 data for each burst.  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, until wrapping on the C_OFFSET_WIDTH boundary with awaddr_offset. */always @(posedge ACLK)  begin          /* Delay write address channel by a few cycles for CR#582705      Only necessary when point2point to AXI_BRAM slave */     if (aresetn_r4 == 0 )       //if (ARESETN == 0)       awvalid <= 1'b0;           // If previously not valid and no throttling, start next transaction

Page 6: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 6/11

     else if (C_M_AXI_SUPPORTS_WRITE && awvalid==0 && aw_throttle == 0)       awvalid <= 1'b1;          /* Once asserted, VALIDs cannot be deasserted, so AWVALID      must wait until transaction is accepted before throttling */     else if (M_AXI_AWREADY && awvalid && aw_throttle)       awvalid <= 1'b0;      else       awvalid <= awvalid;      end   

// Next address after AWREADY indicates previous address acceptancealways @(posedge ACLK)  begin     if (ARESETN == 0)       awaddr_offset <= 'b0;     else if (M_AXI_AWREADY && awvalid)       awaddr_offset <= awaddr_offset + C_M_AXI_BURST_LEN * C_M_AXI_DATA_WIDTH/8;     else       awaddr_offset <= awaddr_offset;  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 channel is valid and readyassign wnext = M_AXI_WREADY & wvalid;

// WVALID logic, similar to the AWVALID always block abovealways @(posedge ACLK)  begin     if (aresetn_r4 == 0 )     //if (ARESETN == 0)       wvalid <= 1'b0;           // If previously not valid and not throttling, start next transaction     else if (C_M_AXI_SUPPORTS_WRITE && wvalid==0 && w_throttle == 0)       wvalid <= 1'b1;

     /* 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 && wlast && w_throttle)       wvalid <= 1'b0; 

Page 7: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 7/11

     else       wvalid <= wvalid;      end

//WLAST generation on the MSB of a counter underflowassign wlast = wlen_count[C_WLEN_COUNT_WIDTH‐1];

/* Burst length counter. Uses extra counter register bit to indicate terminal count to reduce decode logic */    always @(posedge ACLK)  begin     if (ARESETN == 0 || (wnext && wlen_count[C_WLEN_COUNT_WIDTH‐1]))    wlen_count <= C_M_AXI_BURST_LEN ‐ 2;     else if (wnext)    wlen_count <= wlen_count ‐ 1;     else    wlen_count <= wlen_count;  end

/* Write Data Generator Data pattern is only a simple incrementing count from 0 for each burst  */always @(posedge ACLK)  begin     if (ARESETN == 0)       wdata <= 'b0;     else if (wnext && wlast)       wdata <= 'b0;     else if (wnext)       wdata <= wdata + 1;     else       wdata <= 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.  */

//Always accept write responsesalways @(posedge ACLK)  begin     if (ARESETN == 0)    bready <= 1'b0;      else    bready <= C_M_AXI_SUPPORTS_WRITE; end

//Flag any write response errors   assign write_resp_error = bready & M_AXI_BVALID & M_AXI_BRESP[1];

//////////////////////   

Page 8: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 8/11

//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 ACLK)   begin     if (ARESETN == 0)       begin    arvalid <= 1'b0;    araddr_offset  <= 'b0;       end     else if (arvalid && M_AXI_ARREADY)       begin    arvalid <= 1'b0;    araddr_offset <= araddr_offset + C_M_AXI_BURST_LEN * C_M_AXI_DATA_WIDTH/8;       end     else if (C_M_AXI_SUPPORTS_READ && ar_throttle == 0)       begin    arvalid <= 1'b1;    araddr_offset <= araddr_offset;       end     else       begin    arvalid <= arvalid;    araddr_offset <= araddr_offset;       end  end

//////////////////////////////////   //Read Data (and Response) Channel///////////////////////////////////*  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 ACLK)  begin     if (ARESETN == 0)    rready <= 1'b0;      else    rready <= C_M_AXI_SUPPORTS_READ;   end

//Check received read data against data generatoralways @(posedge ACLK)  begin     if (ARESETN == 0)    read_mismatch <= 1'b0;

     //Only check data when RVALID is active      else if ((M_AXI_RVALID && rready) && (M_AXI_RDATA != data_gen))    read_mismatch <= 1'b1;      else    read_mismatch <= 1'b0;   endassign read_resp_error = rready & M_AXI_RVALID & M_AXI_RRESP[1];

Page 9: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 9/11

   ////////////////////////////////////////////Example design read check data generator//////////////////////////////////////////

//Generate expected read data to check against actual read dataalways @(posedge ACLK)  begin     if (ARESETN == 0)       data_gen <= 'b0;

     //On a handshaked cycle, reset if last transfer, otherwise increment     else if (M_AXI_RVALID && rready)       begin    if (M_AXI_RLAST)      data_gen <= 'b0;    else      data_gen <= data_gen + 1;       end     else       data_gen <= data_gen;  end

/////////////////////////////////Example design error register///////////////////////////////

// Register and hold any data mismatches, or read/write interface errors always @(posedge ACLK)  begin     if (ARESETN == 0)       error_reg <= 1'b0;     else if (read_mismatch || write_resp_error || read_resp_error)       error_reg <= 1'b1;     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  */

// Up/down counter of accepted, but not completed, write address commands   always @(posedge ACLK)

Page 10: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 10/11

  begin     if (ARESETN == 0)       aw_issue_count <= 'b0;     else if (bready && M_AXI_BVALID && M_AXI_AWVALID && M_AXI_AWREADY)       aw_issue_count <= aw_issue_count;     else if (bready && M_AXI_BVALID)       aw_issue_count <= aw_issue_count ‐ 1;     else if (M_AXI_AWVALID && M_AXI_AWREADY)       aw_issue_count <= aw_issue_count + 1;     else       aw_issue_count <= aw_issue_count;  end

// Up/down counter of bursts of data written, but not completed with BREADY   always @(posedge ACLK)  begin     if (ARESETN == 0)       w_issue_count <= 'b0;     else if (bready && M_AXI_BVALID && (M_AXI_WLAST & M_AXI_WVALID && M_AXI_WREADY))       w_issue_count <= w_issue_count;     else if (bready && M_AXI_BVALID)       w_issue_count <= w_issue_count ‐ 1;     else if (M_AXI_WLAST & M_AXI_WVALID && M_AXI_WREADY)       w_issue_count <= w_issue_count + 1;     else       w_issue_count <= w_issue_count;  end

// Up/down counter of writes that have been completed, but not yet readalways @(posedge ACLK)  begin     if (ARESETN == 0)    unread_writes <= 'b0;      else if (bready && M_AXI_BVALID && M_AXI_ARVALID && M_AXI_ARREADY)    unread_writes <= unread_writes;      else if (bready && M_AXI_BVALID)    unread_writes <= unread_writes + 1;      else if (M_AXI_ARVALID && M_AXI_ARREADY)    unread_writes <= unread_writes ‐ 1;      else    unread_writes <= unread_writes;  end 

/*If there are fully completed writes, allow reads to start  If the write logic is removed, never throttle reads */always @(unread_writes)  begin     if (unread_writes > 0 || C_M_AXI_SUPPORTS_WRITE == 0)       ar_throttle = 1'b0;     else       ar_throttle = 1'b1;  end

/* If reads supported and the number of completed but not read bursts + issued but not yet completed write addresses is equal or greater than a threshold, throttle the address write channel. */ always @(aw_issue_count,unread_writes)  begin     if (C_M_AXI_SUPPORTS_READ && (aw_issue_count + unread_writes >= C_INTERCONNECT_M_AXI_WRITE_ISSUING))       aw_throttle = 1'b1;     else       aw_throttle = 1'b0;  end

Page 11: Axi3 Master Code

9/17/2015 vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v

http://vserver.13thfloor.at/Stuff/XILINX/axi3_master/repository/axi3_master.v 11/11

/* If the number of completed but not read bursts + issued but not yet completed write addresses is equal or greater than a threshold, throttle the address write channel. */    always @(w_issue_count,unread_writes)  begin     if (C_M_AXI_SUPPORTS_READ && (w_issue_count + unread_writes >= C_INTERCONNECT_M_AXI_WRITE_ISSUING))       w_throttle = 1'b1;     else       w_throttle = 1'b0;  end 

endmodule