axi 4 lite interface description

来源:互联网 发布:python游戏开发源码 编辑:程序博客网 时间:2024/06/05 09:18

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

// User parameters ends
parameter integer C_S_AXI_DATA_WIDTH= 32,
parameter integer C_S_AXI_ADDR_WIDTH= 4
)
(
// Users to add ports here


// User ports ends
input wire  S_AXI_ACLK                                  ,
input wire  S_AXI_ARESETN                               ,


input wire [C_S_AXI_ADDR_WIDTH-1 : 0]   S_AXI_AWADDR    ,
input wire [2 : 0]                      S_AXI_AWPROT    ,
input wire                              S_AXI_AWVALID   ,
output wire                             S_AXI_AWREADY   ,

input wire [C_S_AXI_DATA_WIDTH-1 : 0]   S_AXI_WDATA     , 
input wire [(C_S_AXI_DATA_WIDTH/8)-1:0] S_AXI_WSTRB     ,
input wire                              S_AXI_WVALID    ,
output wire                             S_AXI_WREADY    ,


output wire [1 : 0]                     S_AXI_BRESP     ,
output wire                             S_AXI_BVALID    ,
input wire                              S_AXI_BREADY    ,

input wire [C_S_AXI_ADDR_WIDTH-1 : 0]   S_AXI_ARADDR    ,
input wire [2 : 0]                      S_AXI_ARPROT    ,
input wire                              S_AXI_ARVALID   ,
output wire                             S_AXI_ARREADY   ,

output wire [C_S_AXI_DATA_WIDTH-1 : 0]  S_AXI_RDATA     ,
output wire [1 : 0]                     S_AXI_RRESP     ,
output wire                             S_AXI_RVALID    ,
input wire                              S_AXI_RREADY
);


// AXI4LITE signals
reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr;
reg                          axi_awready;
reg                          axi_wready;
reg [1 : 0]                axi_bresp;
reg                          axi_bvalid;
reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr;
reg                          axi_arready;
reg [C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata;
reg [1 : 0]                axi_rresp;
reg                          axi_rvalid;




// ADDR_LSB is used for addressing 32/64 bit registers/memories
localparam integer ADDR_LSB             = (C_S_AXI_DATA_WIDTH/32) + 1;
localparam integer OPT_MEM_ADDR_BITS    = 1;
//----------------------------------------------
//-- Signals for user logic register space example
//------------------------------------------------


reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg0;
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg1;
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg2;
reg [C_S_AXI_DATA_WIDTH-1:0]slv_reg3;
wire                        slv_reg_rden;
wire                        slv_reg_wren;
reg [C_S_AXI_DATA_WIDTH-1:0]reg_data_out;
integer                        byte_index;


// I/O Connections assignments


assign S_AXI_AWREADY= axi_awready;
assign S_AXI_WREADY   = axi_wready;
assign S_AXI_BRESP   = axi_bresp;
assign S_AXI_BVALID   = axi_bvalid;
assign S_AXI_ARREADY= axi_arready;
assign S_AXI_RDATA   = axi_rdata;
assign S_AXI_RRESP   = axi_rresp;
assign S_AXI_RVALID   = axi_rvalid;
// Implement axi_awready generation
// axi_awready is asserted for one S_AXI_ACLK clock cycle when both
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
// de-asserted when reset is low.


always @( posedge S_AXI_ACLK )
begin
 if ( S_AXI_ARESETN == 1'b0 )
   begin
     axi_awready <= 1'b0;
   end 
 else
   begin    
     if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
       begin   
         // This design expects no outstanding transactions. 
         axi_awready <= 1'b1;
       end
     else           
       begin
         axi_awready <= 1'b0;
       end
   end 
end       


// Implement axi_awaddr latching
// This process is used to latch the address when both 
// S_AXI_AWVALID and S_AXI_WVALID are valid. 


always @( posedge S_AXI_ACLK )
begin
 if ( S_AXI_ARESETN == 1'b0 )
   begin
     axi_awaddr <= 0;
   end 
 else
   begin    
     if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
       begin
         axi_awaddr <= S_AXI_AWADDR;
       end
   end 
end       


// Implement axi_wready generation
// axi_wready is asserted for one S_AXI_ACLK clock cycle when both
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is 
// de-asserted when reset is low. 


always @( posedge S_AXI_ACLK )
begin
 if ( S_AXI_ARESETN == 1'b0 )
   begin
     axi_wready <= 1'b0;
   end 
 else
   begin    
     if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID)
       begin
         // This design expects no outstanding transactions.  
         axi_wready <= 1'b1;
       end
     else
       begin
         axi_wready <= 1'b0;
       end
   end 
end       


// Implement memory mapped register select and write logic generation
// The write data is accepted and written to memory mapped registers when
// axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
// select byte enables of slave registers while writing.
// These registers are cleared when reset (active low) is applied.
// Slave register write enable is asserted when valid address and data are available
// and the slave is ready to accept the write address and write data.
assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;


always @( posedge S_AXI_ACLK )
begin
 if ( S_AXI_ARESETN == 1'b0 )
   begin
     slv_reg0 <= 0;
     slv_reg1 <= 0;
     slv_reg2 <= 0;
     slv_reg3 <= 0;
   end 
 else begin
   if (slv_reg_wren)
     begin
       case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
         2'h0:
           for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
             if ( S_AXI_WSTRB[byte_index] == 1 ) begin
               // Respective byte enables are asserted as per write strobes 
               // Slave register 0
               slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
             end  
         2'h1:
           for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
             if ( S_AXI_WSTRB[byte_index] == 1 ) begin
               // Respective byte enables are asserted as per write strobes 
               // Slave register 1
               slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
             end  
         2'h2:
           for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
             if ( S_AXI_WSTRB[byte_index] == 1 ) begin
               // Respective byte enables are asserted as per write strobes 
               // Slave register 2
               slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
             end  
         2'h3:
           for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
             if ( S_AXI_WSTRB[byte_index] == 1 ) begin
               // Respective byte enables are asserted as per write strobes 
               // Slave register 3
               slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
             end  
         default : begin
                     slv_reg0 <= slv_reg0;
                     slv_reg1 <= slv_reg1;
                     slv_reg2 <= slv_reg2;
                     slv_reg3 <= slv_reg3;
                   end
       endcase
     end
 end
end    


// Implement write response logic generation
// The write response and response valid signals are asserted by the slave 
// when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.  
// This marks the acceptance of address and indicates the status of 
// write transaction.


always @( posedge S_AXI_ACLK )
begin
 if ( S_AXI_ARESETN == 1'b0 )
   begin
     axi_bvalid  <= 0;
     axi_bresp   <= 2'b0;
   end 
 else
   begin    
     if (axi_awready && S_AXI_AWVALID && axi_wready && S_AXI_WVALID && ~axi_bvalid)
       begin
         // indicates a valid write response is available
         axi_bvalid <= 1'b1;
         axi_bresp  <= 2'b0; // 'OKAY' response 
       end                   // work error responses in future
     else
       begin
         if (S_AXI_BREADY && axi_bvalid)   
           begin
             axi_bvalid <= 1'b0; 
           end  
       end
   end
end   


always @( posedge S_AXI_ACLK )
begin
 if ( S_AXI_ARESETN == 1'b0 )
   begin
     axi_arready <= 1'b0;
     axi_araddr  <= 32'b0;
   end 
 else
   begin    
     if (~axi_arready && S_AXI_ARVALID)
       begin
         axi_arready <= 1'b1;
         axi_araddr  <= S_AXI_ARADDR;
       end
     else
       begin
         axi_arready <= 1'b0;
       end
   end 
end       
  
always @( posedge S_AXI_ACLK )
begin
 if ( S_AXI_ARESETN == 1'b0 )
   begin
     axi_rvalid <= 0;
     axi_rresp  <= 0;
   end 
 else
   begin    
     if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)
       begin
         axi_rvalid <= 1'b1;
         axi_rresp  <= 2'b0; // 'OKAY' response
       end   
     else if (axi_rvalid && S_AXI_RREADY)
       begin
         axi_rvalid <= 1'b0;
       end                
   end
end    


// Implement memory mapped register select and read logic generation
// Slave register read enable is asserted when valid address is available
// and the slave is ready to accept the read address.
assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
always @(*)
begin
 if ( S_AXI_ARESETN == 1'b0 )
   begin
     reg_data_out <= 0;
   end 
 else
   begin    
     // Address decoding for reading registers
     case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
       2'h0   : reg_data_out <= slv_reg0;
       2'h1   : reg_data_out <= slv_reg1;
       2'h2   : reg_data_out <= slv_reg2;
       2'h3   : reg_data_out <= slv_reg3;
       default : reg_data_out <= 0;
     endcase
   end   
end


always @( posedge S_AXI_ACLK )
begin
 if ( S_AXI_ARESETN == 1'b0 )
   begin
     axi_rdata  <= 0;
   end 
 else
   begin    
     if (slv_reg_rden)
       begin
         axi_rdata <= reg_data_out;     // register read data
       end   
   end
end    


// Add user logic here


// User logic ends


endmodule

0 0
原创粉丝点击