> 技术文档 > axi_cfg模块开发举例

axi_cfg模块开发举例


module axi_cfg
(
    input        axi_clk,
    input        axi_rstn,
    
    //axi read addr
    input[31:0] axi_araddr,
    output        axi_arready,
    input        axi_arvalid,
    
    //axi read data
    output[31:0] axi_rdata,
    input        axi_rready,
    output        axi_rvalid,
    output[1:0] axi_rresp,
    
    
    //axi write addr
    input [31:0]axi_awaddr,
    output        axi_awready,
    input        axi_awvalid,
    
    input [31:0]axi_wdata,
    output        axi_wready,
    input        axi_wvalid,
    input[3:0]  axi_wstrb,
    
    input         axi_bready,
    output     [1:0]axi_bresp,
    output         axi_bvalid,
    
    
    //cfg interface
    output logic                cfg_wren,
    output logic[31:0]        cfg_wrdata,
    output logic[31:0]        cfg_wraddr,
    
    output    logic            cfg_rden,
    input                cfg_rd_vld,
    input[31:0]            cfg_rd_data
);

    localparam IDLE         = 4\'D0;
    localparam WR_ADDR        = 4\'D1;
    localparam WR_DATA        = 4\'D2;
    localparam WR_RESPONSE    = 4\'D3;
    localparam RD_ADDR        = 4\'D4;
    localparam RD_DATA_WAIT = 4\'D5;
    localparam RD_DATA      = 4\'D6;
    
    
    logic[3:0] axi_state;
    
    always@(posedge axi_clk)begin
        if(axi_rstn==1\'b0)begin
            axi_state <= IDLE;
        end
        else begin
            case(axi_state)
            IDLE:begin
                if(axi_awvalid)begin
                    axi_awready <= 1\'b1;
                    axi_state   <= WR_ADDR;
                end
                else if(axi_arvalid)begin
                    axi_arready <= 1\'b1;
                    axi_state   <= RD_ADDR;
                end
            end
            WR_ADDR:begin
                if(axi_awvalid & axi_awready)begin
                    axi_awready <= 1\'b0;
                    axi_state   <= WR_DATA;
                    cfg_wraddr  <= axi_awaddr;
                    axi_wready  <= 1\'b1;
                end
            end
            WR_DATA:begin
                if(axi_wready & axi_wvalid)begin
                    axi_wready  <= 1\'b0;
                    axi_state   <= WR_RESPONSE;
                    cfg_wren   <= 1\'b1;
                    cfg_wrdata <= axi_wdata;
                    axi_bvalid <= 1\'b1;
                end
            end
            WR_RESPONSE:begin
                if(s_axi_bvalid & s_axi_bready) begin
                    axi_bvalid <= 1\'b0;
                    cfg_wren   <= 1\'b0;
                    axi_state  <= IDLE;
                end
            end
            RD_ADDR:begin
                if(axi_arvalid & axi_arready)begin
                    axi_arready    <= 1\'b0;
                    cfg_wraddr <= axi_araddr;
                    axi_state  <= RD_DATA_WAIT;
                    cfg_rden   <= 1\'b1;
                end
            end
            RD_DATA_WAIT:begin
                cfg_rden   <= 1\'b0;
                if(cfg_rd_vld)begin
                    axi_rvalid <= 1\'b1;
                    axi_rdata <= cfg_rd_data;
                    axi_state  <= RD_DATA;
                end
            end
            RD_DATA:begin
                if(axi_rvalid & axi_rready)begin
                    axi_rvalid <= 1\'b0;
                    axi_state  <= IDLE;
                end
            end
            endcase
        end
    
    end

    

endmodule