Xilinx AXI-LITE读写模块

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2021/08/11 15:33:22
// Design Name: 
// Module Name: axi_lite_tr
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module axi_lite_tr(

    input  write,
    input  read,
    input  [12:0]write_addr,
    input  [12:0]read_addr,
    input  [31:0]write_data,
    output reg [31:0]read_data,
    
    input  s_axi_aclk    ,          //: IN STD_LOGIC;
    input  s_axi_aresetn ,          //: IN STD_LOGIC;
    input  ip2intc_irpt  ,          //: OUT STD_LOGIC;
    
    output reg [12:0]s_axi_awaddr  ,          //: IN STD_LOGIC_VECTOR(12 DOWNTO 0);
    output reg s_axi_awvalid ,          //: IN STD_LOGIC;
    input  s_axi_awready ,          //: OUT STD_LOGIC;
    
    output reg [31:0]s_axi_wdata   ,          //: IN STD_LOGIC_VECTOR(31 DOWNTO 0);
    output reg [3:0]s_axi_wstrb   ,          //: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    output reg s_axi_wvalid  ,          //: IN STD_LOGIC;
    input  s_axi_wready  ,          //: OUT STD_LOGIC;
    
    input  [1:0]s_axi_bresp   ,          //: OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    input  s_axi_bvalid  ,          //: OUT STD_LOGIC;
    output reg s_axi_bready  ,          //: IN STD_LOGIC;
    
    
    output reg [12:0]s_axi_araddr  ,          //: IN STD_LOGIC_VECTOR(12 DOWNTO 0);
    output reg s_axi_arvalid ,          //: IN STD_LOGIC;
    input  s_axi_arready ,          //: OUT STD_LOGIC;
    
    input  [31:0]s_axi_rdata   ,          //: OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
    input  [1:0]s_axi_rresp   ,          //: OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    input  s_axi_rvalid  ,          //: OUT STD_LOGIC;
    output reg s_axi_rready  ,          //: IN STD_LOGIC;
    
    output reg write_done,
    output reg read_done
    );
    
wire w_write,w_read;
reg r_write,r_read;
always @ (posedge s_axi_aclk)    begin
  r_write <= write;
  r_read  <= read;
end
assign w_write = write && (~r_write);
assign w_read  = read  && (~r_read);
//AXI-LITE Write 
parameter W_Idle = 2'b00;
parameter W_write= 2'b01;

(*MARK_DEBUG = "TRUE"*)reg [1:0]W_State = 2'b00;
always @ (posedge s_axi_aclk or negedge s_axi_aresetn)begin
  if(~s_axi_aresetn)begin
    W_State <= W_Idle;
  end
  else begin
    case(W_State)
      W_Idle:begin
        write_done <= 1'b0;
        if(w_write)begin
          W_State <= W_write;
        end
        else begin
          W_State <= W_Idle;
        end
      end
      W_write:begin
        if(s_axi_bvalid && (s_axi_bresp == 2'b00))begin
          W_State <= W_Idle;
          write_done <= 1'b1;
        end
        else begin
          W_State <= W_write;
          write_done <= 1'b0;
        end
      end
      default:begin
        W_State <= W_Idle;
      end
    endcase
  end
end

always @(posedge s_axi_aclk or negedge s_axi_aresetn )begin
  if(~s_axi_aresetn)begin
    s_axi_awaddr <= 13'h0;
    s_axi_awvalid <= 1'b0;
    s_axi_wdata <= 32'h0;
    s_axi_wstrb <= 4'h0;
    s_axi_wvalid<= 1'b0;
    s_axi_bready<= 1'b0;
  end
  else begin
    case(W_State)
      W_Idle:begin
        s_axi_bready <= 1'b0;
        if(w_write)begin
          s_axi_awaddr <= write_addr;
          s_axi_wdata <= write_data;
          s_axi_awvalid <= 1'b1;
          s_axi_wvalid <= 1'b1;
          s_axi_wstrb <= 4'hf;
        end
        else begin
          s_axi_awaddr <= 13'h0;
          s_axi_wdata <= 32'h0;
          s_axi_awvalid <= 1'b0;
          s_axi_wvalid <= 1'b0;
          s_axi_wstrb <= 4'h0;          
        end
      end
      W_write:begin
        if(s_axi_awready && s_axi_wready)begin
          s_axi_awvalid <= 1'b0;
          s_axi_wvalid <= 1'b0;   
          s_axi_bready <= 1'b1;       
        end
      end
      default:begin
        s_axi_awaddr <= 13'h0;
        s_axi_wdata <= 32'h0;
        s_axi_awvalid <= 1'b0;
        s_axi_wvalid <= 1'b0;
        s_axi_wstrb <= 4'h0;  
        s_axi_bready <= 1'b0;       
      end
    endcase
  end
end

//AXI-LITE Read 
parameter R_Idle = 2'b00;
parameter R_Read = 2'b01;
(*MARK_DEBUG = "TRUE"*)reg [1:0]R_State = 2'b00;
always @ (posedge s_axi_aclk or negedge s_axi_aresetn )begin
  if(~s_axi_aresetn)begin
    R_State <= R_Idle;
    read_done <= 1'b0;
  end
  else begin
    case(R_State)
      R_Idle:begin
        read_done <= 1'b0;
        if(w_read)begin
          R_State <= R_Read;
        end
        else begin
          R_State <= R_Idle;
        end
      end
      R_Read:begin
        if(s_axi_rvalid && (s_axi_rresp == 2'b00))begin
          R_State <= R_Idle;
          read_done <= 1'b1;
          read_data <= s_axi_rdata;
        end
        else begin
          R_State <= R_Read;
          read_done <= 1'b0;
        end
      end
      default:begin
        R_State <= R_Idle;
      end
    endcase
  end
end 
always @ (posedge s_axi_aclk or negedge s_axi_aresetn )begin
  if(~s_axi_aresetn)begin
    s_axi_araddr <= 13'h0;
    s_axi_arvalid <= 1'b0;
    s_axi_rready <= 1'b0;    
  end
  else begin
    case(R_State)
      R_Idle:begin
        if(w_read)begin
          s_axi_araddr <= read_addr;
          s_axi_arvalid <= 1'b1;
          s_axi_rready <= 1'b1;
        end
        else begin
          s_axi_araddr <= 13'h0;
          s_axi_arvalid <= 1'b0;
          s_axi_rready <= 1'b0;           
        end
      end
      R_Read:begin
        if(s_axi_arready )begin
          s_axi_araddr <= 13'h0;
          s_axi_arvalid <= 1'b0;          
        end
      end
      default:begin
        s_axi_araddr <= 13'h0;
        s_axi_arvalid <= 1'b0;
        s_axi_rready <= 1'b0;        
      end
    endcase
  end
end
endmodule

1、write/read信号的上升沿触发读/写操作

2、读写操作完成后产生write_done/read_done脉冲信号

3、以太网帧格式:四种格式的以太网帧结构_闲云野鹤,悠悠垂钓的技术博客_51CTO博客

原文地址:https://www.cnblogs.com/dlutccj/p/15131364.html