精华内容
下载资源
问答
  • VIVADO的AXI时序

    千次阅读 2019-08-18 23:15:57
    文章目录AXI liteAXI full AXI lite 写时序时序 AXI full 写时序时序

    突发长度、突发大小、突发类型、突发地址

    在这里插入图片描述
    在这里插入图片描述

    读/写操作的依赖关系

    写操作

    在这里插入图片描述
    在这里插入图片描述

    读操作

    在这里插入图片描述
    在这里插入图片描述

    封装工具生成的IP

    AXI lite

    VHDL代码

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity led_control_s_axi is
        generic (
            C_S_AXI_DATA_WIDTH  : integer   := 32;
            C_S_AXI_ADDR_WIDTH  : integer   := 4
        );
        port (
            ---------------------------------------------------
            -- 用户端口
            ---------------------------------------------------
            led_flash_en    : out std_logic;
            led_flash_time  : out std_logic_vector(31 downto 0);
            test            : out std_logic_vector(127 downto 0);
            ---------------------------------------------------
            -- Axi Slave Bus Interface
            ---------------------------------------------------
            S_AXI_ACLK      : in  std_logic;
            S_AXI_ARESETN   : in  std_logic;
            S_AXI_AWADDR    : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
            S_AXI_AWPROT    : in  std_logic_vector(2 downto 0);
            S_AXI_AWVALID   : in  std_logic;
            S_AXI_AWREADY   : out std_logic;
            S_AXI_WDATA     : in  std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
            S_AXI_WSTRB     : in  std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
            S_AXI_WVALID    : in  std_logic;
            S_AXI_WREADY    : out std_logic;
            S_AXI_BRESP     : out std_logic_vector(1 downto 0);
            S_AXI_BVALID    : out std_logic;
            S_AXI_BREADY    : in  std_logic;
            S_AXI_ARADDR    : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
            S_AXI_ARPROT    : in  std_logic_vector(2 downto 0);
            S_AXI_ARVALID   : in  std_logic;
            S_AXI_ARREADY   : out std_logic;
            S_AXI_RDATA     : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
            S_AXI_RRESP     : out std_logic_vector(1 downto 0);
            S_AXI_RVALID    : out std_logic;
            S_AXI_RREADY    : in  std_logic
        );
    end led_control_s_axi;
    
    architecture arch_imp of led_control_s_axi is
    
    -------------------------------------------------------------------------------
    --          常量声明
    -------------------------------------------------------------------------------
        -- local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
        -- ADDR_LSB is used for addressing 32/64 bit registers/memories
        -- ADDR_LSB = 2 for 32 bits (n downto 2)
        -- ADDR_LSB = 3 for 64 bits (n downto 3)
        constant ADDR_LSB               : integer := (C_S_AXI_DATA_WIDTH/32)+ 1;
        constant OPT_MEM_ADDR_BITS      : integer := 1;
    
    -------------------------------------------------------------------------------
    --          信号声明
    -------------------------------------------------------------------------------
        ---- AXI4LITE signals
        signal axi_awaddr   : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
        signal axi_awready  : std_logic;
        signal axi_wready   : std_logic;
        signal axi_bresp    : std_logic_vector(1 downto 0);
        signal axi_bvalid   : std_logic;
        signal axi_araddr   : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
        signal axi_arready  : std_logic;
        signal axi_rdata    : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
        signal axi_rresp    : std_logic_vector(1 downto 0);
        signal axi_rvalid   : std_logic;
    
        ---- Signals for user logic register space example
        signal slv_reg0     : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
        signal slv_reg1     : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
        signal slv_reg2     : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
        signal slv_reg3     : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
        signal slv_reg_rden : std_logic;
        signal slv_reg_wren : std_logic;
        signal reg_data_out : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
        signal byte_index   : integer;
        signal aw_en        : std_logic;
    
    begin
        
        -- I/O Connections assignments
        S_AXI_AWREADY   <= axi_awready;
        S_AXI_WREADY    <= axi_wready;
        S_AXI_BRESP     <= axi_bresp;
        S_AXI_BVALID    <= axi_bvalid;
        S_AXI_ARREADY   <= axi_arready;
        S_AXI_RDATA     <= axi_rdata;
        S_AXI_RRESP     <= axi_rresp;
        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.
        -----------------------------------
        -- Implement axi_awaddr latching
        -- This process is used to latch the address when both S_AXI_AWVALID and S_AXI_WVALID are valid.
        -------------------------------------------------------
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then
                if S_AXI_ARESETN = '0' then
                    axi_awready <= '0';
                    aw_en       <= '1';
                    axi_awaddr  <= (others => '0');
                else
                    if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' and aw_en = '1') then
                        -- slave is ready to accept write address when there is a valid write address and write data on the write address and data bus. 
                        -- This design expects no outstanding transactions.
                        axi_awready <= '1';
                        aw_en       <= '0';
                        axi_awaddr  <= S_AXI_AWADDR;
                    elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then
                        axi_awready <= '0';
                        aw_en       <= '1';
                    else
                        axi_awready <= '0';
                    end if;
                end if;
            end if;
        end process;
    
        -- 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.
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then
                if S_AXI_ARESETN = '0' then
                    axi_wready <= '0';
                else
                    if (axi_wready = '0' and S_AXI_WVALID = '1' and S_AXI_AWVALID = '1' and aw_en = '1') then
                        -- slave is ready to accept write data when there is a valid write address and write data on the write address and data bus. 
                        -- This design expects no outstanding transactions.
                        axi_wready <= '1';
                    else
                        axi_wready <= '0';
                    end if;
                end if;
            end if;
        end process;
        
        -- 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.
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then
                if S_AXI_ARESETN = '0' then
                    axi_bvalid  <= '0';
                    axi_bresp   <= "00"; --need to work more on the responses
                else
                    if (axi_awready = '1' and S_AXI_AWVALID = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0'  ) then
                        axi_bvalid <= '1';
                        axi_bresp  <= "00";
                    elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then   --check if bready is asserted while bvalid is high)
                        axi_bvalid <= '0';                                 -- (there is a possibility that bready is always asserted high)
                    end if;
                end if;
            end if;
        end process;
        
        
        -- Implement axi_arready generation
        -- axi_arready is asserted for one S_AXI_ACLK clock cycle when S_AXI_ARVALID is asserted. axi_awready is de-asserted when reset (active low) is asserted.
        -- The read address is also latched when S_AXI_ARVALID is asserted. axi_araddr is reset to zero on reset assertion
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then
                if S_AXI_ARESETN = '0' then
                    axi_arready <= '0';
                    axi_araddr  <= (others => '1');
                else
                    if (axi_arready = '0' and S_AXI_ARVALID = '1') then
                        axi_arready <= '1';
                        axi_araddr  <= S_AXI_ARADDR;
                    else
                        axi_arready <= '0';
                    end if;
                end if;
            end if;
        end process;
    
        -- Implement axi_arvalid generation
        -- axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
        -- S_AXI_ARVALID and axi_arready are asserted. The slave registers
        -- data are available on the axi_rdata bus at this instance. The
        -- assertion of axi_rvalid marks the validity of read data on the
        -- bus and axi_rresp indicates the status of read transaction.axi_rvalid
        -- is deasserted on reset (active low). axi_rresp and axi_rdata are
        -- cleared to zero on reset (active low).
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then
                if S_AXI_ARESETN = '0' then
                    axi_rvalid <= '0';
                    axi_rresp  <= "00";
                else
                    if (axi_arready = '1' and S_AXI_ARVALID = '1' and axi_rvalid = '0') then
                        axi_rvalid <= '1';
                        axi_rresp  <= "00"; -- 'OKAY' response
                    elsif (axi_rvalid = '1' and S_AXI_RREADY = '1') then
                        axi_rvalid <= '0';
                    end if;
                end if;
            end if;
        end process;
        
        -- 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. 
        -- 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.
        slv_reg_wren <= axi_wready and S_AXI_WVALID and axi_awready and S_AXI_AWVALID ;
        process (S_AXI_ACLK)
            variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
        begin
            if rising_edge(S_AXI_ACLK) then
                if S_AXI_ARESETN = '0' then
                    slv_reg0 <= (others => '0');
                    slv_reg1 <= (others => '0');
                    slv_reg2 <= (others => '0');
                    slv_reg3 <= (others => '0');
                else
                    loc_addr := axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
                    if (slv_reg_wren = '1') then
                        case loc_addr is
                            when b"00" =>
                                for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
                                    if ( S_AXI_WSTRB(byte_index) = '1' ) then
                                        slv_reg0(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
                                    end if;
                                end loop;
                            when b"01" =>
                                for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
                                    if ( S_AXI_WSTRB(byte_index) = '1' ) then
                                        slv_reg1(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
                                    end if;
                                end loop;
                            when b"10" =>
                                for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
                                    if ( S_AXI_WSTRB(byte_index) = '1' ) then
                                        slv_reg2(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
                                    end if;
                                end loop;
                            when b"11" =>
                                for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
                                    if ( S_AXI_WSTRB(byte_index) = '1' ) then
                                        slv_reg3(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
                                    end if;
                                end loop;
                            when others =>
                                slv_reg0 <= slv_reg0;
                                slv_reg1 <= slv_reg1;
                                slv_reg2 <= slv_reg2;
                                slv_reg3 <= slv_reg3;
                        end case;
                    end if;
                end if;
            end if;
        end process;
    
        -- 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.
        slv_reg_rden <= axi_arready and S_AXI_ARVALID and (not axi_rvalid) ;
        process (slv_reg0, slv_reg1, slv_reg2, slv_reg3, axi_araddr, S_AXI_ARESETN, slv_reg_rden)
            variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
        begin
            -- Address decoding for reading registers
            loc_addr := axi_araddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
            case loc_addr is
                when b"00" =>
                    reg_data_out <= slv_reg0;
                when b"01" =>
                    reg_data_out <= slv_reg1;
                when b"10" =>
                    reg_data_out <= slv_reg2;
                when b"11" =>
                    reg_data_out <= slv_reg3;
                when others =>
                    reg_data_out  <= (others => '0');
            end case;
        end process;
    
        -- Output register or memory read data
        process( S_AXI_ACLK ) is
        begin
            if (rising_edge (S_AXI_ACLK)) then
                if ( S_AXI_ARESETN = '0' ) then
                    axi_rdata  <= (others => '0');
                else
                    if (slv_reg_rden = '1') then
                        axi_rdata <= reg_data_out;
                    end if;
                end if;
            end if;
        end process;
        
        -------------------------------------------------------
        -- 用户逻辑
        -------------------------------------------------------
        led_flash_en    <= slv_reg0(0);
        led_flash_time  <= slv_reg1;
        
        -------------------------------------------------------
        -- 观测信号
        -------------------------------------------------------
        test(3 downto 0)   <= axi_awaddr;
        test(         4)   <= axi_awready;
        test(         5)   <= axi_wready;
        test(7 downto 6)   <= axi_bresp;
        test(         8)   <= axi_bvalid;
        test(12 downto 9)  <= axi_araddr;
        test(          13) <= axi_arready;
        test(45 downto 14) <= axi_rdata;
        test(47 downto 46) <= axi_rresp;
        test(48)           <= axi_rvalid;
        test(49)           <= aw_en;
        test(53 downto 50) <= S_AXI_AWADDR;
        test(56 downto 54) <= S_AXI_AWPROT;
        test(57)           <= S_AXI_AWVALID;
        test(89 downto 58) <= S_AXI_WDATA;
        test(93 downto 90) <= S_AXI_WSTRB;
        test(          94) <= S_AXI_WVALID;
        test(          95) <= S_AXI_BREADY;
        test(99 downto 96) <= S_AXI_ARADDR;
        test(102 downto 100) <= S_AXI_ARPROT;
        test(         103)  <= S_AXI_ARVALID;
        test(         104)  <= S_AXI_RREADY;
        test(127 downto 105) <= (others=>'0');
        
    end arch_imp;
    
    

    写时序
    在这里插入图片描述
    读时序
    在这里插入图片描述

    AXI full

    VHDL代码

    library ieee;
        use ieee.std_logic_1164.all;
        use ieee.numeric_std.all;
    
    entity full_test_S_AXI is
        generic (
            ---------------------------------------------------
            -- AXI参数
            ---------------------------------------------------
            C_S_AXI_ID_WIDTH        : integer   := 1;
            C_S_AXI_DATA_WIDTH      : integer   := 32;
            C_S_AXI_ADDR_WIDTH      : integer   := 6;
            C_S_AXI_AWUSER_WIDTH    : integer   := 1;
            C_S_AXI_ARUSER_WIDTH    : integer   := 1;
            C_S_AXI_WUSER_WIDTH     : integer   := 1;
            C_S_AXI_RUSER_WIDTH     : integer   := 1;
            C_S_AXI_BUSER_WIDTH     : integer   := 1
        );
        port (
            ---------------------------------------------------
            -- 用户端口
            ---------------------------------------------------
            test            : out std_logic_vector(255 downto 0);
            ---------------------------------------------------
            -- AXI FULL 端口
            ---------------------------------------------------
            S_AXI_ACLK      : in  std_logic;
            S_AXI_ARESETN   : in  std_logic;
            S_AXI_AWID      : in  std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0);
            S_AXI_AWADDR    : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
            S_AXI_AWLEN     : in  std_logic_vector(7 downto 0);
            S_AXI_AWSIZE    : in  std_logic_vector(2 downto 0);
            S_AXI_AWBURST   : in  std_logic_vector(1 downto 0);
            S_AXI_AWLOCK    : in  std_logic;
            S_AXI_AWCACHE   : in  std_logic_vector(3 downto 0);
            S_AXI_AWPROT    : in  std_logic_vector(2 downto 0);
            S_AXI_AWQOS     : in  std_logic_vector(3 downto 0);
            S_AXI_AWREGION  : in  std_logic_vector(3 downto 0);
            S_AXI_AWUSER    : in  std_logic_vector(C_S_AXI_AWUSER_WIDTH-1 downto 0);
            S_AXI_AWVALID   : in  std_logic;
            S_AXI_AWREADY   : out std_logic;
            S_AXI_WDATA     : in  std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
            S_AXI_WSTRB     : in  std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
            S_AXI_WLAST     : in  std_logic;
            S_AXI_WUSER     : in  std_logic_vector(C_S_AXI_WUSER_WIDTH-1 downto 0);
            S_AXI_WVALID    : in  std_logic;
            S_AXI_WREADY    : out std_logic;
            S_AXI_BID       : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0);
            S_AXI_BRESP     : out std_logic_vector(1 downto 0);
            S_AXI_BUSER     : out std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0);
            S_AXI_BVALID    : out std_logic;
            S_AXI_BREADY    : in  std_logic;
            S_AXI_ARID      : in  std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0);
            S_AXI_ARADDR    : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
            S_AXI_ARLEN     : in  std_logic_vector(7 downto 0);
            S_AXI_ARSIZE    : in  std_logic_vector(2 downto 0);
            S_AXI_ARBURST   : in  std_logic_vector(1 downto 0);
            S_AXI_ARLOCK    : in  std_logic;
            S_AXI_ARCACHE   : in  std_logic_vector(3 downto 0);
            S_AXI_ARPROT    : in  std_logic_vector(2 downto 0);
            S_AXI_ARQOS     : in  std_logic_vector(3 downto 0);
            S_AXI_ARREGION  : in  std_logic_vector(3 downto 0);
            S_AXI_ARUSER    : in  std_logic_vector(C_S_AXI_ARUSER_WIDTH-1 downto 0);
            S_AXI_ARVALID   : in  std_logic;
            S_AXI_ARREADY   : out std_logic;
            S_AXI_RID       : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0);
            S_AXI_RDATA     : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
            S_AXI_RRESP     : out std_logic_vector(1 downto 0);
            S_AXI_RLAST     : out std_logic;
            S_AXI_RUSER     : out std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0);
            S_AXI_RVALID    : out std_logic;
            S_AXI_RREADY    : in  std_logic
        );
    end full_test_S_AXI;
    
    architecture arch_imp of full_test_S_AXI is
    -------------------------------------------------------------------------------
    --                              常量声明
    -------------------------------------------------------------------------------
        constant ADDR_LSB           : integer := (C_S_AXI_DATA_WIDTH/32)+ 1;
        constant OPT_MEM_ADDR_BITS  : integer := 3;
        constant USER_NUM_MEM       : integer := 1;
        constant ALL_ZEROS          : std_logic_vector (C_S_AXI_ADDR_WIDTH - 1 downto 0) := "000000";
    
    -------------------------------------------------------------------------------
    --                              信号声明
    -------------------------------------------------------------------------------
        ---------------------------------------------------
        -- AXI4 FULL signals
        ---------------------------------------------------
        signal axi_awaddr           : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
        signal axi_awready          : std_logic;
        signal axi_wready           : std_logic;
        signal axi_bresp            : std_logic_vector(1 downto 0);
        signal axi_buser            : std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0);
        signal axi_bvalid           : std_logic;
        signal axi_araddr           : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
        signal axi_arready          : std_logic;
        signal axi_rdata            : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
        signal axi_rresp            : std_logic_vector(1 downto 0);
        signal axi_rlast            : std_logic;
        signal axi_ruser            : std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0);
        signal axi_rvalid           : std_logic;
        signal aw_wrap_en           : std_logic;                        -- aw_wrap_en determines wrap boundary and enables wrapping
        signal ar_wrap_en           : std_logic;                        -- ar_wrap_en determines wrap boundary and enables wrapping
        signal aw_wrap_size         : integer;                  
        signal ar_wrap_size         : integer;                  
        signal axi_awv_awr_flag     : std_logic;                        -- The axi_awv_awr_flag flag marks the presence of write address valid
        signal axi_arv_arr_flag     : std_logic;                        --The axi_arv_arr_flag flag marks the presence of read address valid
            
        signal axi_awlen_cntr       : std_logic_vector(7 downto 0);     -- The axi_awlen_cntr internal write address counter to keep track of beats in a burst transaction
        signal axi_arlen_cntr       : std_logic_vector(7 downto 0);     --The axi_arlen_cntr internal read address counter to keep track of beats in a burst transaction
        signal axi_arburst          : std_logic_vector(2-1 downto 0);
        signal axi_awburst          : std_logic_vector(2-1 downto 0);
        signal axi_arlen            : std_logic_vector(8-1 downto 0);
        signal axi_awlen            : std_logic_vector(8-1 downto 0);
    
        ------------------------------------------------
        ---- Signals for user logic memory space example
        --------------------------------------------------
        type ram_type is array (2**OPT_MEM_ADDR_BITS-1 downto 0) of std_logic_vector (C_S_AXI_DATA_WIDTH-1 downto 0);
        signal RAM                  : ram_type;
        signal ram_data_in          : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
        signal ram_data_out         : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
        signal ram_wren,ram_rden    : std_logic;
        signal ram_address          : std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
    
    begin
    
        -- I/O Connections assignments
        S_AXI_AWREADY   <= axi_awready;
        S_AXI_WREADY    <= axi_wready;
        S_AXI_BRESP     <= axi_bresp;
        S_AXI_BUSER     <= axi_buser;
        S_AXI_BVALID    <= axi_bvalid;
        S_AXI_ARREADY   <= axi_arready;
        S_AXI_RDATA     <= axi_rdata;
        S_AXI_RRESP     <= axi_rresp;
        S_AXI_RLAST     <= axi_rlast;
        S_AXI_RUSER     <= axi_ruser;
        S_AXI_RVALID    <= axi_rvalid;
        S_AXI_BID       <= S_AXI_AWID;
        S_AXI_RID       <= S_AXI_ARID;
        aw_wrap_size    <= ((C_S_AXI_DATA_WIDTH)/8 * to_integer(unsigned(axi_awlen))); 
        ar_wrap_size    <= ((C_S_AXI_DATA_WIDTH)/8 * to_integer(unsigned(axi_arlen))); 
        aw_wrap_en      <= '1' when (((axi_awaddr AND std_logic_vector(to_unsigned(aw_wrap_size,C_S_AXI_ADDR_WIDTH))) XOR std_logic_vector(to_unsigned(aw_wrap_size,C_S_AXI_ADDR_WIDTH))) = ALL_ZEROS) else 
                           '0';
        ar_wrap_en      <= '1' when (((axi_araddr AND std_logic_vector(to_unsigned(ar_wrap_size,C_S_AXI_ADDR_WIDTH))) XOR std_logic_vector(to_unsigned(ar_wrap_size,C_S_AXI_ADDR_WIDTH))) = ALL_ZEROS) else 
                           '0';
    
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then 
                if S_AXI_ARESETN = '0' then
                    axi_awready <= '0';
                    axi_awv_awr_flag <= '0';
                else
                    if (axi_awready = '0' and S_AXI_AWVALID = '1' and axi_awv_awr_flag = '0' and axi_arv_arr_flag = '0') then
                        -- slave is ready to accept an address and associated control signals
                        axi_awv_awr_flag  <= '1'; -- used for generation of bresp() and bvalid
                        axi_awready <= '1';
                    elsif (S_AXI_WLAST = '1' and axi_wready = '1') then 
                    -- preparing to accept next address after current write burst tx completion
                        axi_awv_awr_flag  <= '0';
                    else
                        axi_awready <= '0';
                    end if;
                end if;
            end if;         
        end process; 
        
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then 
                if S_AXI_ARESETN = '0' then
                    axi_awaddr      <= (others => '0');
                    axi_awburst     <= (others => '0'); 
                    axi_awlen       <= (others => '0'); 
                    axi_awlen_cntr  <= (others => '0');
                else
                    if (axi_awready = '0' and S_AXI_AWVALID = '1' and axi_awv_awr_flag = '0') then
                        -- address latching
                        axi_awaddr      <= S_AXI_AWADDR(C_S_AXI_ADDR_WIDTH - 1 downto 0);  ---- start address of transfer
                        axi_awlen_cntr  <= (others => '0');
                        axi_awburst     <= S_AXI_AWBURST;
                        axi_awlen       <= S_AXI_AWLEN;
                    elsif((axi_awlen_cntr <= axi_awlen) and axi_wready = '1' and S_AXI_WVALID = '1') then     
                        axi_awlen_cntr <= std_logic_vector(unsigned(axi_awlen_cntr) + 1);
                        case (axi_awburst) is
                            when "00" =>    -- fixed burst
                                -- The write address for all the beats in the transaction are fixed
                                axi_awaddr     <= axi_awaddr;       ----for awsize = 4 bytes (010)
                            when "01" =>    --incremental burst
                                -- The write address for all the beats in the transaction are increments by awsize
                                axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--awaddr aligned to 4 byte boundary
                                axi_awaddr(ADDR_LSB-1 downto 0)  <= (others => '0');  ----for awsize = 4 bytes (010)
                            when "10" =>    --Wrapping burst
                                -- The write address wraps when the address reaches wrap boundary 
                                if (aw_wrap_en = '1') then
                                    axi_awaddr <= std_logic_vector (unsigned(axi_awaddr) - (to_unsigned(aw_wrap_size,C_S_AXI_ADDR_WIDTH)));                
                                else 
                                    axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--awaddr aligned to 4 byte boundary
                                    axi_awaddr(ADDR_LSB-1 downto 0)  <= (others => '0');  ----for awsize = 4 bytes (010)
                                end if;
                            when others => --reserved (incremental burst for example)
                                axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_awaddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--for awsize = 4 bytes (010)
                                axi_awaddr(ADDR_LSB-1 downto 0)  <= (others => '0');
                        end case;        
                    end if;
                end if;
            end if;
        end process;
        
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then 
                if S_AXI_ARESETN = '0' then
                    axi_wready <= '0';
                else
                    if (axi_wready = '0' and S_AXI_WVALID = '1' and axi_awv_awr_flag = '1') then
                        axi_wready <= '1';
                        -- elsif (axi_awv_awr_flag = '0') then
                    elsif (S_AXI_WLAST = '1' and axi_wready = '1') then 
            
                        axi_wready <= '0';
                    end if;
                end if;
            end if;         
        end process; 
        
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then 
                if S_AXI_ARESETN = '0' then
                    axi_bvalid  <= '0';
                    axi_bresp  <= "00"; --need to work more on the responses
                    axi_buser <= (others => '0');
                else
                    if (axi_awv_awr_flag = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0' and S_AXI_WLAST = '1' ) then
                        axi_bvalid <= '1';
                        axi_bresp  <= "00"; 
                    elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then  
                    --check if bready is asserted while bvalid is high)
                        axi_bvalid <= '0';                      
                    end if;
                end if;
            end if;         
        end process; 
        
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then 
                if S_AXI_ARESETN = '0' then
                    axi_arready <= '0';
                    axi_arv_arr_flag <= '0';
                else
                    if (axi_arready = '0' and S_AXI_ARVALID = '1' and axi_awv_awr_flag = '0' and axi_arv_arr_flag = '0') then
                        axi_arready <= '1';
                        axi_arv_arr_flag <= '1';
                    elsif (axi_rvalid = '1' and S_AXI_RREADY = '1' and (axi_arlen_cntr = axi_arlen)) then 
                        -- preparing to accept next address after current read completion
                        axi_arv_arr_flag <= '0';
                    else
                        axi_arready <= '0';
                    end if;
                end if;
            end if;         
        end process; 
         
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then 
                if S_AXI_ARESETN = '0' then
                    axi_araddr <= (others => '0');
                    axi_arburst <= (others => '0');
                    axi_arlen <= (others => '0'); 
                    axi_arlen_cntr <= (others => '0');
                    axi_rlast <= '0';
                    axi_ruser <= (others => '0');
                else
                    if (axi_arready = '0' and S_AXI_ARVALID = '1' and axi_arv_arr_flag = '0') then
                        -- address latching 
                        axi_araddr <= S_AXI_ARADDR(C_S_AXI_ADDR_WIDTH - 1 downto 0); ---- start address of transfer
                        axi_arlen_cntr <= (others => '0');
                        axi_rlast <= '0';
                        axi_arburst <= S_AXI_ARBURST;
                        axi_arlen <= S_AXI_ARLEN;
                    elsif((axi_arlen_cntr <= axi_arlen) and axi_rvalid = '1' and S_AXI_RREADY = '1') then     
                        axi_arlen_cntr <= std_logic_vector (unsigned(axi_arlen_cntr) + 1);
                        axi_rlast <= '0';      
                    
                        case (axi_arburst) is
                            when "00" =>  -- fixed burst
                                -- The read address for all the beats in the transaction are fixed
                                axi_araddr <= axi_araddr;      ----for arsize = 4 bytes (010)
                            when "01" =>  --incremental burst
                                -- The read address for all the beats in the transaction are increments by awsize
                                axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1); --araddr aligned to 4 byte boundary
                                axi_araddr(ADDR_LSB-1 downto 0)  <= (others => '0');  ----for awsize = 4 bytes (010)
                            when "10" =>  --Wrapping burst
                                -- The read address wraps when the address reaches wrap boundary 
                                if (ar_wrap_en = '1') then   
                                    axi_araddr <= std_logic_vector (unsigned(axi_araddr) - (to_unsigned(ar_wrap_size,C_S_AXI_ADDR_WIDTH)));
                                else 
                                    axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1); --araddr aligned to 4 byte boundary
                                    axi_araddr(ADDR_LSB-1 downto 0)  <= (others => '0');  ----for awsize = 4 bytes (010)
                                end if;
                            when others => --reserved (incremental burst for example)
                                axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB) <= std_logic_vector (unsigned(axi_araddr(C_S_AXI_ADDR_WIDTH - 1 downto ADDR_LSB)) + 1);--for arsize = 4 bytes (010)
                                axi_araddr(ADDR_LSB-1 downto 0)  <= (others => '0');
                        end case;         
                    elsif((axi_arlen_cntr = axi_arlen) and axi_rlast = '0' and axi_arv_arr_flag = '1') then  
                        axi_rlast <= '1';
                    elsif (S_AXI_RREADY = '1') then  
                        axi_rlast <= '0';
                    end if;
                end if;
            end if;
        end  process;  
    
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then
                if S_AXI_ARESETN = '0' then
                    axi_rvalid <= '0';
                    axi_rresp  <= "00";
                else
                    if (axi_arv_arr_flag = '1' and axi_rvalid = '0') then
                        axi_rvalid <= '1';
                        axi_rresp  <= "00"; -- 'OKAY' response
                    elsif (axi_rvalid = '1' and S_AXI_RREADY = '1') then
                        axi_rvalid <= '0';
                    end  if;      
                end if;
            end if;
        end  process;
    
        ---------------------------------------------------------------------------
        -- 用户逻辑
        ---------------------------------------------------------------------------
        ram_wren    <= axi_wready and S_AXI_WVALID ;
        ram_rden    <= axi_arv_arr_flag ;
        ram_address <= axi_araddr(ADDR_LSB+OPT_MEM_ADDR_BITS downto ADDR_LSB) when axi_arv_arr_flag = '1' else
                       axi_awaddr(ADDR_LSB+OPT_MEM_ADDR_BITS downto ADDR_LSB) when axi_awv_awr_flag = '1' else
                       (others => '0');
        ram_data_in <= S_AXI_WDATA;
        process (S_AXI_ACLK)
        begin
            if rising_edge(S_AXI_ACLK) then
                if ram_wren = '1' then
                    RAM(to_integer(unsigned(ram_address))) <= ram_data_in;
                end if;
                ram_data_out <= RAM(to_integer(unsigned(ram_address)));
            end if;
        end process;
    
        process(ram_data_out, axi_rvalid) is
        begin
            if (axi_rvalid = '1') then
                axi_rdata <= ram_data_out;
            else
                axi_rdata <= (others => '0');
            end if;  
        end process;
    
        ---------------------------------------------------------------------------
        -- 观测信号
        ---------------------------------------------------------------------------
        test(             0) <= S_AXI_ACLK;
        test(             1) <= S_AXI_ARESETN;
        test(             2) <= S_AXI_AWID(0);
        test(  8 downto   3) <= S_AXI_AWADDR;
        test(             9) <= '0';
        test( 17 downto  10) <= S_AXI_AWLEN;
        test( 20 downto  18) <= S_AXI_AWSIZE;
        test( 22 downto  21) <= S_AXI_AWBURST;
        test(            23) <= S_AXI_AWLOCK;
        test( 27 downto  24) <= S_AXI_AWCACHE;
        test( 30 downto  28) <= S_AXI_AWPROT;
        test( 34 downto  31) <= S_AXI_AWQOS;
        test( 38 downto  35) <= S_AXI_AWREGION;
        test(            39) <= S_AXI_AWVALID;
        test( 71 downto  40) <= S_AXI_WDATA;
        test( 75 downto  72) <= S_AXI_WSTRB;
        test(            76) <= S_AXI_WLAST;
        test(            77) <= S_AXI_WVALID;
        test(            78) <= S_AXI_BREADY;
        test(            79) <= S_AXI_ARID(0);
        test( 85 downto  80) <= S_AXI_ARADDR;
        test(            86) <= '0';
        test( 94 downto  87) <= S_AXI_ARLEN;
        test( 97 downto  95) <= S_AXI_ARSIZE;
        test( 99 downto  98) <= S_AXI_ARBURST;
        test(           100) <= S_AXI_ARLOCK;
        test(104 downto 101) <= S_AXI_ARCACHE;
        test(107 downto 105) <= S_AXI_ARPROT;
        test(111 downto 108) <= S_AXI_ARQOS;
        test(115 downto 112) <= S_AXI_ARREGION;
        test(           116) <= S_AXI_ARVALID;
        test(           117) <= S_AXI_RREADY;
        test(           118) <= axi_awready;
        test(           119) <= axi_wready;
        test(           120) <= axi_bresp(0);
        test(           121) <= axi_bvalid;
        test(           122) <= axi_arready;
        test(154 downto 123) <= axi_rdata;
        test(156 downto 155) <= axi_rresp;
        test(           157) <= axi_rlast;
        test(           158) <= axi_rvalid;
        test(           159) <= S_AXI_AWID(0);
        test(           160) <= S_AXI_ARID(0);
        test(255 downto 161) <= (others=>'0');
        
    end arch_imp;
    
    

    注意memcpy的使用对读写时序的影响

    C代码1

    在这里插入图片描述
    写时序
    在这里插入图片描述
    读时序
    在这里插入图片描述

    C代码2

    写时序
    在这里插入图片描述
    读时序
    在这里插入图片描述

    C代码3

    在这里插入图片描述
    写时序
    在这里插入图片描述
    读时序
    在这里插入图片描述

    操控AXI BRAM

    library ieee;
        use ieee.std_logic_1164.all;
        use ieee.numeric_std.all;
    
    entity bram_op_wrapper is
    port(
        clk          : in  std_logic;
        rst          : in  std_logic;
    
        user_wr_en   : in  std_logic;
        user_wr_len  : in  std_logic_vector( 7 downto 0);       --突发传输数据个数-1
        user_wr_addr : in  std_logic_vector(11 downto 0);
        user_wr_data : in  std_logic_vector(31 downto 0);
    
        user_rd_en   : in  std_logic;
        user_rd_len  : in  std_logic_vector( 7 downto 0);
        user_rd_addr : in  std_logic_vector(11 downto 0);
        user_rd_data : out std_logic_vector(31 downto 0);
        user_rd_vld  : out std_logic
    );
    end bram_op_wrapper;
    
    architecture Behavioral of bram_op_wrapper is
    
    --------------------------------------------------------------------------------
    --                      类型定义
    --------------------------------------------------------------------------------
        type aw_state_type is (AW_ST0,AW_ST1,AW_ST2,AW_ST3);
        type w_state_type  is (W_ST0,W_ST1,W_ST2);
        type ar_state_type is (AR_ST0,AR_ST1,AR_ST2,AR_ST3);
        type r_state_type  is (R_ST0,R_ST1,R_ST2);
    
    --------------------------------------------------------------------------------
    --                      component声明
    --------------------------------------------------------------------------------
        component AXI_BRAM
            port (
                rsta_busy       : out std_logic;
                rstb_busy       : out std_logic;
                s_aclk          : in  std_logic;
                s_aresetn       : in  std_logic;
                s_axi_awid      : in  std_logic_vector(3 downto 0);
                s_axi_awaddr    : in  std_logic_vector(31 downto 0);
                s_axi_awlen     : in  std_logic_vector(7 downto 0);
                s_axi_awsize    : in  std_logic_vector(2 downto 0);
                s_axi_awburst   : in  std_logic_vector(1 downto 0);
                s_axi_awvalid   : in  std_logic;
                s_axi_awready   : out std_logic;
                s_axi_wdata     : in  std_logic_vector(31 downto 0);
                s_axi_wstrb     : in  std_logic_vector(3 downto 0);
                s_axi_wlast     : in  std_logic;
                s_axi_wvalid    : in  std_logic;
                s_axi_wready    : out std_logic;
                s_axi_bid       : out std_logic_vector(3 downto 0);
                s_axi_bresp     : out std_logic_vector(1 downto 0);
                s_axi_bvalid    : out std_logic;
                s_axi_bready    : in  std_logic;
                s_axi_arid      : in  std_logic_vector(3 downto 0);
                s_axi_araddr    : in  std_logic_vector(31 downto 0);
                s_axi_arlen     : in  std_logic_vector(7 downto 0);
                s_axi_arsize    : in  std_logic_vector(2 downto 0);
                s_axi_arburst   : in  std_logic_vector(1 downto 0);
                s_axi_arvalid   : in  std_logic;
                s_axi_arready   : out std_logic;
                s_axi_rid       : out std_logic_vector(3 downto 0);
                s_axi_rdata     : out std_logic_vector(31 downto 0);
                s_axi_rresp     : out std_logic_vector(1 downto 0);
                s_axi_rlast     : out std_logic;
                s_axi_rvalid    : out std_logic;
                s_axi_rready    : in  std_logic
            );
        end component;
    
        component FWFT_FIFO_W44_D512
            port (
                clk     : in  std_logic;
                srst    : in  std_logic;
                din     : in  std_logic_vector(43 downto 0);
                wr_en   : in  std_logic;
                rd_en   : in  std_logic;
                dout    : out std_logic_vector(43 downto 0);
                full    : out std_logic;
                empty   : out std_logic
            );
        end component;
    
    --------------------------------------------------------------------------------
    --                      信号声明
    --------------------------------------------------------------------------------
        -- axi bram相关信号
        signal s_aresetn       : std_logic;
        signal s_axi_awid      : std_logic_vector(3 downto 0);
        signal s_axi_awaddr    : std_logic_vector(31 downto 0);
        signal s_axi_awlen     : std_logic_vector(7 downto 0);
        signal s_axi_awsize    : std_logic_vector(2 downto 0);
        signal s_axi_awburst   : std_logic_vector(1 downto 0);
        signal s_axi_awvalid   : std_logic;
        signal s_axi_awready   : std_logic;
        signal s_axi_wdata     : std_logic_vector(31 downto 0);
        signal s_axi_wstrb     : std_logic_vector(3 downto 0);
        signal s_axi_wlast     : std_logic;
        signal s_axi_wvalid    : std_logic;
        signal s_axi_wready    : std_logic;
        signal s_axi_bid       : std_logic_vector(3 downto 0);
        signal s_axi_bresp     : std_logic_vector(1 downto 0);
        signal s_axi_bvalid    : std_logic;
        signal s_axi_bready    : std_logic;
        signal s_axi_arid      : std_logic_vector(3 downto 0);
        signal s_axi_araddr    : std_logic_vector(31 downto 0);
        signal s_axi_arlen     : std_logic_vector(7 downto 0);
        signal s_axi_arsize    : std_logic_vector(2 downto 0);
        signal s_axi_arburst   : std_logic_vector(1 downto 0);
        signal s_axi_arvalid   : std_logic;
        signal s_axi_arready   : std_logic;
        signal s_axi_rid       : std_logic_vector(3 downto 0);
        signal s_axi_rdata     : std_logic_vector(31 downto 0);
        signal s_axi_rresp     : std_logic_vector(1 downto 0);
        signal s_axi_rlast     : std_logic;
        signal s_axi_rvalid    : std_logic;
        signal s_axi_rready    : std_logic;
    
        -- 写缓冲FIFO信号
        signal wr_fifo_din     : std_logic_vector(43 downto 0);
        signal wr_fifo_wr_en   : std_logic;
        signal wr_fifo_rd_en   : std_logic;
        signal wr_fifo_dout    : std_logic_vector(43 downto 0);
        signal wr_fifo_full    : std_logic;
        signal wr_fifo_empty   : std_logic;
    
        -- 读缓冲FIFO信号
        signal rd_fifo_din     : std_logic_vector(43 downto 0);
        signal rd_fifo_wr_en   : std_logic;
        signal rd_fifo_rd_en   : std_logic;
        signal rd_fifo_dout    : std_logic_vector(43 downto 0);
        signal rd_fifo_full    : std_logic;
        signal rd_fifo_empty   : std_logic;
    
        -- 复位信号
        signal rst_L1          : std_logic := '0';
        signal rst_cnt         : unsigned(7 downto 0) := (others=>'0');
    
        -- axi状态
        signal aw_state        : aw_state_type := AW_ST0;
        signal w_state         : w_state_type  := W_ST0;
        signal ar_state        : ar_state_type := AR_ST0;
        signal r_state         : r_state_type  := R_ST0;
                               
        signal wr_cnt          : unsigned(7 downto 0) := (others=>'0');
        
    begin
    
        -----------------------------------------------------------------
        -- axi复位
        process(clk)
        begin
            if rising_edge(clk) then
                rst_L1 <= rst;
                if (rst_L1='0') and (rst='1') then
                    rst_cnt <= (others=>'0');
                elsif (rst_cnt<20) then
                    rst_cnt <= rst_cnt + 1;
                else
                    rst_cnt <= rst_cnt;
                end if;
    
                if (rst_cnt<20) then
                    s_aresetn <= '0';
                else
                    s_aresetn <= '1';
                end if;
            end if;
        end process;
    
        -----------------------------------------------------------------
        -- 状态机
        process(clk)
        begin
            if rising_edge(clk) then
                case aw_state is
                    when AW_ST0 =>
                        if (wr_fifo_empty='0') then                     -- FIFO中有数据,跳转状态
                            aw_state  <= AW_ST1;
                        else
                            aw_state  <= AW_ST0;
                        end if;
                    when AW_ST1 =>
                        if (s_axi_awready='1') then
                            aw_state  <= AW_ST2;
                        else
                            aw_state  <= AW_ST1;
                        end if;
                    when AW_ST2 =>
                        if (wr_cnt=unsigned(user_wr_len)) then
                            aw_state  <= AW_ST3;
                        else
                            aw_state  <= AW_ST2;
                        end if;
                    when AW_ST3 =>
                        aw_state      <= AW_ST0;
                    when others =>
                        aw_state      <= AW_ST0;
                end case;
            
                case w_state is
                    when W_ST0 =>
                        wr_cnt            <= (others=>'0');
                        if (wr_fifo_empty='0') then                     -- FIFO中有数据,跳转状态
                            w_state       <= W_ST1;
                        else              
                            w_state       <= W_ST0;
                        end if;
                    when W_ST1 =>
                        if (s_axi_wready='1') then
                            wr_cnt        <= wr_cnt + 1;
                        else
                            wr_cnt        <= wr_cnt;
                        end if;
                        if (wr_cnt=unsigned(user_wr_len)) then
                            w_state       <= W_ST2;
                        else
                            w_state       <= W_ST1;
                        end if;
                    when W_ST2 =>
                        wr_cnt            <= (others=>'0');
                        w_state           <= W_ST0;
                    when others =>
                        w_state           <= W_ST0;
                end case;
            end if;
        end process;
        
         -- 写地址通道
        s_axi_awid    <= "0000";
        s_axi_awsize  <= "010";
        s_axi_awburst <= "01";
        s_axi_awlen   <= user_wr_len;
        s_axi_awaddr  <=  std_logic_vector(to_unsigned(0,18)) & wr_fifo_dout(43 downto 32) & "00";    -- 设置突发写地址
        process(aw_state)
        begin
            case aw_state is
                when AW_ST0  =>
                    s_axi_awvalid <= '0';
                when AW_ST1  =>
                    s_axi_awvalid <= '1';
                when AW_ST2  =>
                    s_axi_awvalid <= '0';
                when others  =>
                    s_axi_awvalid <= '0';
            end case;
        end process;
        
        -- 写数据通道
        s_axi_wstrb   <= "1111";
        s_axi_wdata   <= wr_fifo_dout(31 downto 0);
        process(s_axi_wready,wr_fifo_empty,w_state,wr_cnt)
        begin
            case w_state is
                when W_ST0  =>
                    wr_fifo_rd_en <= '0';
                    s_axi_wlast   <= '0';
                    s_axi_wvalid  <= '0';
                when W_ST1  =>
                     wr_fifo_rd_en <= s_axi_wready and (not wr_fifo_empty);
                     if (wr_cnt=unsigned(user_wr_len)) then
                        s_axi_wlast <= '1';
                     else
                        s_axi_wlast <= '0';
                     end if;
                     s_axi_wvalid <= '1';
                when W_ST2  =>
                    wr_fifo_rd_en <= '0';
                    s_axi_wlast   <= '0';
                    s_axi_wvalid  <= '0';
                when others =>
                    wr_fifo_rd_en <= '0';
                    s_axi_wlast   <= '0';
                    s_axi_wvalid  <= '0';
            end case;
        end process;
    
        -- 写响应通道
        process(s_axi_bresp,s_axi_bvalid)
        begin
            if (s_axi_bresp="00") and (s_axi_bvalid='1') then
                s_axi_bready <= '1';
            else
                s_axi_bready <= '0';
            end if;
        end process;
    
        -----------------------------------------------------------------
        -- 状态机
        process(clk)
        begin
            if rising_edge(clk) then
                case ar_state is
                    when AR_ST0 =>
                        if (rd_fifo_empty='0') then                     -- FIFO中有数据,跳转状态
                            ar_state  <= AR_ST1;
                        else
                            ar_state  <= AR_ST0;
                        end if;
                    when AR_ST1 =>
                        if (s_axi_arready='1') then
                            ar_state  <= AR_ST2;
                        else
                            ar_state  <= AR_ST1;
                        end if;
                    when AR_ST2 =>
                        if (s_axi_rlast='1') then
                            ar_state  <= AR_ST3;
                        else
                            ar_state  <= AR_ST2;
                        end if;
                    when AR_ST3 =>
                        ar_state      <= AR_ST0;
                    when others =>
                        ar_state      <= AR_ST0;
                end case;
                
                case r_state is
                    when R_ST0 =>
                         if (rd_fifo_empty='0') then                     -- FIFO中有数据,跳转状态
                             r_state <= R_ST1;
                         else
                             r_state <= R_ST0;
                         end if;
                    when R_ST1 =>
                        if (s_axi_rlast='1') then
                            r_state  <= R_ST2;
                        else
                            r_state  <= R_ST1;
                        end if;
                    when R_ST2 =>
                        r_state      <= R_ST0;
                    when others =>
                        r_state      <= R_ST0;
                end case;
            end if;
        end process;
        
        -- 读地址通道
        s_axi_arid    <= (others=>'0');
        s_axi_arsize  <= "010";
        s_axi_arburst <= "01";
        s_axi_arlen   <= user_rd_len;
        s_axi_araddr  <= std_logic_vector(to_unsigned(0,18)) & rd_fifo_dout(43 downto 32) & "00";    -- 设置突发读地址
        process(ar_state)
        begin
            case ar_state is
                when AR_ST0 =>
                     s_axi_arvalid <= '0';
                when AR_ST1 =>
                     s_axi_arvalid <= '1';
                when AR_ST2 =>
                     s_axi_arvalid <= '0';
                when AR_ST3 =>
                     s_axi_arvalid <= '0';
                when others =>
                     s_axi_arvalid <= '0';
            end case;
        end process;
        
        -- 读数据通道
        process(r_state,s_axi_rlast,s_axi_rvalid,s_axi_rdata)
        begin
            case r_state is
                when R_ST0 =>
                     s_axi_rready  <= '0'; 
                     rd_fifo_rd_en <= '0'; 
                     user_rd_vld   <= '0';
                     user_rd_data  <= (others=>'0');
                when R_ST1 =>
                    if (s_axi_rlast='1') then
                        rd_fifo_rd_en <= '1';
                    else
                        rd_fifo_rd_en <= '0';
                    end if;
                    s_axi_rready  <= '1';
                    user_rd_vld  <= s_axi_rvalid;
                    user_rd_data <= s_axi_rdata;
                when R_ST2 =>
                    s_axi_rready  <= '0';
                    rd_fifo_rd_en <= '0';
                when others =>
                    s_axi_rready  <= '0';
                    rd_fifo_rd_en <= '0';
                    user_rd_vld   <= '0';
                    user_rd_data  <= (others=>'0');
            end case;
        end process;
        
        -----------------------------------------------------------------
        -- 例化axi bram
        Inst_AXI_BRAM : AXI_BRAM
        port map(
            rsta_busy       => open,
            rstb_busy       => open,
            s_aclk          => clk,
            s_aresetn       => s_aresetn,
    
            s_axi_awid      => s_axi_awid,
            s_axi_awaddr    => s_axi_awaddr,
            s_axi_awlen     => s_axi_awlen,
            s_axi_awsize    => s_axi_awsize,
            s_axi_awburst   => s_axi_awburst,
            s_axi_awvalid   => s_axi_awvalid,
            s_axi_awready   => s_axi_awready,
    
            s_axi_wdata     => s_axi_wdata,
            s_axi_wstrb     => s_axi_wstrb,
            s_axi_wlast     => s_axi_wlast,
            s_axi_wvalid    => s_axi_wvalid,
            s_axi_wready    => s_axi_wready,
    
            s_axi_bid       => s_axi_bid,
            s_axi_bresp     => s_axi_bresp,
            s_axi_bvalid    => s_axi_bvalid,
            s_axi_bready    => s_axi_bready,
    
            s_axi_arid      => s_axi_arid,
            s_axi_araddr    => s_axi_araddr,
            s_axi_arlen     => s_axi_arlen,
            s_axi_arsize    => s_axi_arsize,
            s_axi_arburst   => s_axi_arburst,
            s_axi_arvalid   => s_axi_arvalid,
            s_axi_arready   => s_axi_arready,
    
            s_axi_rid       => s_axi_rid,
            s_axi_rdata     => s_axi_rdata,
            s_axi_rresp     => s_axi_rresp,
            s_axi_rlast     => s_axi_rlast,
            s_axi_rvalid    => s_axi_rvalid,
            s_axi_rready    => s_axi_rready
        );
    
        -----------------------------------------------------------------
        -- 例化FIFO
        wr_fifo_wr_en <= user_wr_en;
        wr_fifo_din   <= user_wr_addr & user_wr_data;
        Inst_WR_FWFT_FIFO_W44_D512 : FWFT_FIFO_W44_D512
        port map(
            clk   => clk,
            srst  => rst,
            din   => wr_fifo_din,
            wr_en => wr_fifo_wr_en,
            rd_en => wr_fifo_rd_en,
            dout  => wr_fifo_dout,
            full  => wr_fifo_full,
            empty => wr_fifo_empty
        ); 
    
        rd_fifo_wr_en <= user_rd_en;
        rd_fifo_din   <= user_rd_addr & X"00000000";
        Inst_RD_FWFT_FIFO_W44_D512 : FWFT_FIFO_W44_D512
        port map(
            clk   => clk,
            srst  => rst,
            din   => rd_fifo_din,
            wr_en => rd_fifo_wr_en,
            rd_en => rd_fifo_rd_en,
            dout  => rd_fifo_dout,
            full  => rd_fifo_full,
            empty => rd_fifo_empty
        );
    
    end Behavioral;
    

    博文链接

    ZYNQ+Vivado2015.2系列(七)软硬件联合Debug观察AXI总线读、写时各信号的时序
    AXI4 & AXI4-stream 相关笔记
    AXI协议中的模棱两可的含义的解释
    【JokerのZYNQ7020】AXI4_FULL。

    展开全文
  • 本人在写JESD204B的AXI4-Lite配置接口时,发现对端口时序的理解和常规的理解不一样,因此写这篇文章以作记录,具体如下。 1.1 写时序异常 按常规理解的时序图(参照SRIO)写出来的代码,ready是因,valid是果。在...
  • zynq中的axi操作时序

    2017-10-10 11:26:04
    详细介绍axi时序以及如何来实现axi的通信 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。...
  • AXI总线时序基本分析

    2020-03-10 21:24:44
    1.握手协议简介 (1)主要信号...关于AXI-lite接口与源码分析:https://blog.csdn.net/NarutoInspire/article/details/81455589 (2)AXI的突发传输机制:https://blog.csdn.net/l471094842/article/details/91977087

    1.握手协议简介
    (1)主要信号包括Address、data、control information,响应信号VALID/READY信号匹配(即两信号同时有效)来完成握手操作。

    2.信道总线分类
    (1)写地址信道(Write address channel)
    (2)写数据信道(Write data channel)
    (3)写响应信道(Write response channel)
    (4)读地址信道(Read address channel)
    (5)读数据信道(Read data channel)
    其中并没有读响应总线,只要读取的地址一到即把数据送出去

    3.写操作的时序:VALID与READY匹配
    (1)VALID信号在READY信号之前有效
    在这里插入图片描述
    INFO有效同时VALID信号有效,而READY慢一拍,因此VALID信号要再保持一拍,直到下一个时钟上升沿到来,采样到地址与数据。
    (2)READY信号比VALID信号提前到来。
    在这里插入图片描述
    READY也需要等待一拍,在源端VALID信号在T2之后有效,在T3时完成了一次单周期传输。
    (3)VALID信号和READY信号同时有效
    在这里插入图片描述
    在T2周期完成采样。

    4.信号名含义
    每一个信道都有自己的握手信号对(VALID/READY)
    写地址信道 AWVALID/AWREADY
    写数据信道 WVALID/WREADY
    写相应信道 BVALID/BREADY
    读地址信道 ARVALID/ARREADY
    读数据信道 RVALID/RREADY
    一般而言,尽量使READY信号比VALID信号提前到来,实际上只要符合以上三种时序都可支持。

    5.参考文章
    (1)LITE占用了很少的逻辑资源,不支持突发传输,属于轻量级传输总线。关于AXI-lite接口与源码分析:https://blog.csdn.net/NarutoInspire/article/details/81455589
    (2)AXI的突发传输机制:https://blog.csdn.net/l471094842/article/details/91977087

    展开全文
  • AXI stream接口时序

    2021-02-20 11:37:21
    二、握手机制 只有当VALID 和READY 同时为高时,才能进行传输。...由于AXI4-Stream协议(amba4_axi4_stream_v1_0_protocol_spec.pdf)没有时序图,因此,我使用XILINX公司的产品指导手册(pg007_srio_gen2_v3_1.pdf

    二、握手机制

    只有当VALID 和READY 同时为高时,才能进行传输。

    VALID和READY信号的先后顺序有一下三种形式:
    2.1  VALID早于READY信号
    READY信号早于VALID信号
    VALID 信号与 READY 信号同时
    三、基本事务

    AXI4-Stream跟AXI4的区别就是AXI4-Stream去除了地址线,这样就不涉及读写数据的概念了,只有简单的发送与接收说法,减少了延时。由于AXI4-Stream协议(amba4_axi4_stream_v1_0_protocol_spec.pdf)没有时序图,因此,我使用XILINX公司的产品指导手册(pg007_srio_gen2_v3_1.pdf)里的一个时序图来演示AXI4-Stream各个信号的关系。如下图所示:
    在这里插入图片描述
    上图中,tready信号一直处于高电平,表示从设备做好了接收数据准备。tvalid变为高电平的同时,tdata、tkeep、tuser也同时进行发送。在tdata最后一个字节数据时,tlast发送一个高电平脉冲。数据发送完成后,tvalid变为低电平。这样一次传输就完成了。

    展开全文
  • AXI总线协议时序

    千次阅读 2019-02-13 15:44:54
    由于ZYNQ架构和常用接口IP核经常出现 AXI协议,赛灵思的协议手册讲解时序比较分散。所以笔者收藏AXI协议的几种时序,方便编程。 (1) AXI_LITE协议: ( 1) 读地址通道, 包含ARVALID, ARADDR, ARREADY信号; ( 2)...

    由于ZYNQ架构和常用接口IP核经常出现 AXI协议,赛灵思的协议手册讲解时序比较分散。所以笔者收藏AXI协议的几种时序,方便编程。
    (1) AXI_LITE协议:
    ( 1) 读地址通道, 包含ARVALID, ARADDR, ARREADY信号;
    ( 2) 读数据通道, 包含RVALID, RDATA, RREADY, RRESP信号;
    ( 3) 写地址通道, 包含AWVALID, AWADDR, AWREADY信号;
    ( 4) 写数据通道, 包含WVALID, WDATA, WSTRB, WREADY信号;
    ( 5) 写应答通道, 包含BVALID, BRESP, BREADY信号;( 6) 系统通道, 包含: ACLK, ARESETN信号。

    AXI4总线和AXI4-Lite总线的信号也有他的命名特点:读地址信号都是以AR开头( A: address; R: read)写地址信号都是以AW开头( A: address; W: write)读数据信号都是以R开头( R: read)写数据信号都是以W开头( W: write)
     

    AXI_LITE读时序:

    AXI_LITE:写时序

    (2) AXI_STREAM:
    AXI4-Stream总线的组成有:
    ( 1) ACLK信号: 总线时钟, 上升沿有效;
    ( 2) ARESETN信号: 总线复位, 低电平有效
    ( 3) TREADY信号: 从机告诉主机做好传输准备;
    ( 4) TDATA信号: 数据, 可选宽度32,64,128,256bit
    ( 5) TSTRB信号: 每一bit对应TDATA的一个有效字节, 宽度为TDATA/8
    ( 6) TLAST信号: 主机告诉从机该次传输为突发传输的结尾;
    ( 7) TVALID信号: 主机告诉从机数据本次传输有效;
    ( 8) TUSER信号 : 用户定义信号, 宽度为128bit。

    (3)其他

    (a)AXI架构

    AXI协议是基于burst的传输,并且定义了以下5个独立的传输通道:读地址通道、读数据通道、写地址通道、写数据通道、写响应通道。

    地址通道携带控制消息用于描述被传输的数据属性,数据传输使用写通道来实现“主”到“从”的传输,“从”使用写响应通道来完成一次写传输;读通道用来实现数据从“从”到“主”的传输。

                                    图3-1  读结构

                                        图3-2 写架构

    AXI是基于VALID/READY的握手机制数据传输协议,传输源端使用VALID表明地址/控制信号、数据是有效的,目的端使用READY表明自己能够接受信息。

    读/写地址通道:读、写传输每个都有自己的地址通道,对应的地址通道承载着对应传输的地址控制信息。

    读数据通道:读数据通道承载着读数据和读响应信号包括数据总线(8/16/32/64/128/256/512/1024bit)和指示读传输完成的读响应信号。

    写数据通道:写数据通道的数据信息被认为是缓冲(buffered)了的,“主”无需等待“从”对上次写传输的确认即可发起一次新的写传输。写通道包括数据总线(8/16…1024bit)和字节线(用于指示8bit 数据信号的有效性)。

    写响应通道:“从”使用写响应通道对写传输进行响应。所有的写传输需要写响应通道的完成信号。

                                  图3-4 接口与互联

    AXI协议提供单一的接口定义,能用在下述三种接口之间:master/interconnect、slave/interconnect、master/slave。

    可以使用以下几种典型的系统拓扑架构:

    共享地址与数据总线 
    共享地址总线,多数据总线 
    multilayer多层,多地址总线,多数据总线 
    在大多数系统中,地址通道的带宽要求没有数据通道高,因此可以使用共享地址总线,多数据总线结构来对系统性能和互联复杂度进行平衡。

    寄存器片(Register Slices):

    每个AXI通道使用单一方向传输信息,并且各个通道直接没有任何固定关系。因此可以可以在任何通道任何点插入寄存器片,当然这会导致额外的周期延迟。

    使用寄存器片可以实现周期延迟(cycles of latency)和最大操作频率的折中;使用寄存器片可以分割低速外设的长路径。

    (b)信号描述

    表 2-1 全局信号

    表 2-2 写地址通道信号

    表 2-3 写数据通道信号 

    表 2-4 写响应通道信号 

    表 2-5 读地址通道信号

    表 2-6 读数据通道信号 

    表 2-7 低功耗接口信号 

    (c) 信号接口要求

    3.1时钟复位

    时钟

    每个AXI组件使用一个时钟信号ACLK,所有输入信号在ACLK上升沿采样,所有输出信号必须在ACLK上升沿后发生。

    复位

    AXI使用一个低电平有效的复位信号ARESETn,复位信号可以异步断言,但必须和时钟上升沿同步去断言。

    复位期间对接口有如下要求:①主机接口必须驱动ARVALID,AWVALID,WVALID为低电平;②从机接口必须驱动RVALID,BVALID为低电平;③所有其他信号可以被驱动到任意值。

    在复位后,主机可以在时钟上升沿驱动ARVALID,AWVALID,WVALID为高电平。

    3.2基本读写传输

    握手过程

    5个传输通道均使用VALID/READY信号对传输过程的地址、数据、控制信号进行握手。使用双向握手机制,传输仅仅发生在VALID、READY同时有效的时候。下图是几种握手机制:

    图 3-1 VALID before READY 握手 

    图 3-2 READY before VALID 握手

    图 3-3 VALID with READY 握手

    通道信号要求

    通道握手信号:每个通道有自己的xVALID/xREADY握手信号对。

    写地址通道:当主机驱动有效的地址和控制信号时,主机可以断言AWVALID,一旦断言,需要保持AWVALID的断言状态,直到时钟上升沿采样到从机的AWREADY。AWREADY默认值可高可低,推荐为高(如果为低,一次传输至少需要两个周期,一个用来断言AWVALID,一个用来断言AWREADY);当AWREADY为高时,从机必须能够接受提供给它的有效地址。

    写数据通道:在写突发传输过程中,主机只能在它提供有效的写数据时断言WVALID,一旦断言,需要保持断言状态,知道时钟上升沿采样到从机的WREADY。WREADY默认值可以为高,这要求从机总能够在单个周期内接受写数据。主机在驱动最后一次写突发传输是需要断言WLAST信号。

    写响应通道:从机只能它在驱动有效的写响应时断言BVALID,一旦断言需要保持,直到时钟上升沿采样到主机的BREADY信号。当主机总能在一个周期内接受写响应信号时,可以将BREADY的默认值设为高。

    读地址通道:当主机驱动有效的地址和控制信号时,主机可以断言ARVALID,一旦断言,需要保持ARVALID的断言状态,直到时钟上升沿采样到从机的ARREADY。ARREADY默认值可高可低,推荐为高(如果为低,一次传输至少需要两个周期,一个用来断言ARVALID,一个用来断言ARREADY);当ARREADY为高时,从机必须能够接受提供给它的有效地址。

    读数据通道:只有当从机驱动有效的读数据时从机才可以断言RVALID,一旦断言需要保持直到时钟上升沿采样到主机的BREADY。BREADY默认值可以为高,此时需要主机任何时候一旦开始读传输就能立马接受读数据。当最后一次突发读传输时,从机需要断言RLAST。

    通道间关系

    AXI协议要求通道间满足如下关系:

    写响应必须跟随最后一次burst的的写传输 
    读数据必须跟随数据对应的地址 
    通道握手信号需要确认一些依耐关系 
    通道握手信号的依耐关系

    展开全文
  • AXI总线是一种高性能、高带宽、低延迟的片内总线,AXI协议描述了主从设备数据传输的方式。主设备和从设备通过握手信号建立连接(VALID和READY),握手信号包括主机发送的VALID信号,表示数据有效,从机发送的READY...
  • 针对AXI4总线设备之间的高速数据传输需求,根据AXI4总线协议,设计实现了一种基于FPGA的AXI4总线读写时序控制方法。以FPGA为核心,采用VHDL语言,完成了满足AXI4总线协议的读猝发方式数据传输和写猝发方式数据传输...
  • 如果你能搜到此篇文章,我就默认你对AXI4-Stream有了一个大致的了解(至少知道此协议不包含任何地址映射,仅仅是一串数据流)。 本文是基于video in IP的对视频信号转AXI4-Stream信号的验证。因为博主现在不用OV5640...
  • JESD204B的AXI4-Lite时序分析 1.前言 本人在写JESD204B的AXI4-Lite配置接口时,发现对端口时序的理解和常规的理解不一样,因此写这篇文章以作记录,具体如下。 1.1写时序异常 按常规理解的时序图(参照SRIO)写...
  • AXI4读操作           图 4‑15 读通道架构   如上图所示,主设备向从设备通过读地址通道指定读数据地址及控制信号,从设备通过读数据通道将指定地址上的数据传输给主设备。           图4...
  • AXI_02 AXI4总线简介(协议、时序

    千次阅读 2019-03-07 11:47:37
    由于该系列文章阅读有顺序性,所以请跳转至该系列文章第一篇从头开始阅读,并按照文章末尾指示按顺序阅读,否则会云里雾里,传送门在此: https://blog.csdn.net/qq_33486907/article/details/88289714 《AXI_01 ...
  • AXI 接口----时序基础

    2020-04-30 11:44:41
      最近跟着V3学院尤老师在学习ZYNQ,其中一个很重要的部分是ZYNQ中的AXI接口。在这里将AXI接口的时许进行一下记录,便于将来的查阅。 1、AXI结构   AXI 的结构如下图所示;可以将 AXI 的 master 和 slave 之间的...
  • 一、 MIG 控制器概述 7 系列 FPGA 存储器接口解决方案核心如图所示。 二、 用户 FPGA 逻辑接口 ... AXI4 从站接口将 AXI4 事务映射到 UI,以向内存控制器提供行业标准总线协议接口。 用户界面块和用户界面 ...
  • 转载:原文 ...但是从机模式是被动接收数据,而不能主动的去获取数据,因此计划研究一下AXI Master接口的IP核的构建方法。 1. 利用向导创建AXI Lite Master测试用例 在这一步,AXI类型为...
  • 每一个AXI组件使用一个单独的时钟aclk,上升沿采样; 在主接口和从接口上,输入和输出信号之间不能有组合逻辑路径; 复位 低电平有效 支持异步复位,但是必须同步释放 复位期间主端必须驱动ARVALID, AWVALID, ...
  • 学习关于AXI总线的信号接口的具体要求 Single Interface Requirements Clock and Reset 前面也提到了信号和复位的功能,这里对AXI全局时钟(ACLK)和复位信号(ARESETn)做进一步的解释说明。 Clock: 每个AXI组件都...
  • 虽然Xilinx已经将和AXI时序有关的细节都封装起来,给出了官方IP和向导生成自定义IP,用户只需要关注自己的逻辑实现,但是还是有必要简单了解一下AXI的时序,毕竟咱是做硬件设计的。  AXI(Advanced eXtensible ...
  • 虽然Xilinx已经将和AXI时序有关的细节都封装起来,给出了官方IP和向导生成自定义IP,用户只需要关注自己的逻辑实现,但是还是有必要简单了解一下AXI的时序,毕竟咱是做硬件设计的。  AXI(Advanced eXtensible ...
  • 0.引言 通过之前的学习,可以在PL端创建从机模式的AXI接口IP核。但是从机模式是被动接收数据,而不能主动的去获取数据,因此计划研究一下AXI Master接口的IP核的构建方法。 1.利用向导创建AXI Lite ...
  • 前面一节我们学会了创建基于AXI总线的IP,但是对于AXI协议各信号的时序还不太了解。这个实验就是通过SDK和Vivado联合调试观察AXI总线的信号。由于我们创建的接口是基于AXI_Lite协议的,所以我们实际观察到是AXI_Lite...
  • AXI4

    2014-07-17 15:29:06
    AXI 4中的信号均为时序logic,在时钟边沿
  • AXI总线详细解析

    2018-05-30 21:06:50
    详细介绍AXI总线的时序以及握手过程,每个环节都面面俱到。
  • axi 1.0

    2011-06-16 19:47:00
    AXI : Advanced eXtensible Interface ? 它的地址/控制和数据相位是分离的,支持不对齐的数据传输 ? 同时在突发传输中,只...并更加容易就行时序收敛 ? AXI4-Lite, AXI4-Stream ? how seperate channels b...
  • 一、AXI总线简介 AXI是AMBA中一个新的高性能协议。AXI技术丰富了现有的AMBA标准内容,满足超高性能和复杂的片上...地址和数据通道分开,能对每一个通道进行单独优化,可以根据需要控制时序通道,将时钟频率提高到最高
  • zcu102_8_AXI_STREAM实现AXI_DMA

    千次阅读 多人点赞 2019-01-09 18:13:14
    AXI_STREAM的时序 AXI_STREAM接口一般用于大规模持续的无地址映射关系的流数据传输 数据从master单向流动至slave, 参考自定义IP生成的示例代码进行说明 master端接口如下: // Master Stream Ports. TVALID ...
  • AXI总线详解完结篇

    千次阅读 2020-11-29 00:09:35
    4、AXI总线详解-AXI4读写操作时序AXI4猝发地址及选择 5、AXI4交换机制 6、ZYNQ中DMA与AXI4总线-DMA简介 7、AXI总线详解-不同类型的DMA 8、AXI总线详解-DMA内部寄存器的读写方式 9、AXI总线详解-几种应用DMA的场合 ...
  • AMBA 3 AXI specification

    2018-09-10 21:36:33
    它的地址/控制和数据相位是分离的,支持不对齐的数据传输,同时在突发传输中,只需要首地址,同时分离的读写数据通道、并支持Outstanding传输访问和乱序访问,并更加容易进行时序收敛。AXI 是AMBA 中一个新的高性能...
  • 知乎用户ljgibbs授权转发 本系列我想深入探寻 AXI4 ...声明1:部分时序图以及部分语句来自 ARM AMBA 官方手册 (有的时候感觉手册写得太好了,忍不住就直接翻译了。。) 声明2:AXI 总线是 ARM 公司的知识产权 备...

空空如也

空空如也

1 2 3 4 5 6
收藏数 115
精华内容 46
关键字:

axi时序