⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ram_loader.vhd

📁 spi boot loader souce opencore.org
💻 VHD
字号:
----------------------------------------------------------------------------------- SD/MMC Bootloader-- Sample client for loading an image to asynchronous SRAM---- $Id: ram_loader.vhd 77 2009-04-01 19:53:14Z arniml $---- Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org)---- All rights reserved, see COPYING.---- Redistribution and use in source and synthezised forms, with or without-- modification, are permitted provided that the following conditions are met:---- Redistributions of source code must retain the above copyright notice,-- this list of conditions and the following disclaimer.---- Redistributions in synthesized form must reproduce the above copyright-- notice, this list of conditions and the following disclaimer in the-- documentation and/or other materials provided with the distribution.---- Neither the name of the author nor the names of other contributors may-- be used to endorse or promote products derived from this software without-- specific prior written permission.---- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE-- POSSIBILITY OF SUCH DAMAGE.---- Please report bugs to the author, but before you do so, please-- make sure that this is not a derivative work and that-- you have the latest version of this file.---- The latest version of this file can be found at:--      http://www.opencores.org/projects.cgi/web/spi_boot/overview---------------------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;entity ram_loader is  port (    -- Global Interface -------------------------------------------------------    clk_i      : in    std_logic;    reset_i    : in    std_logic;    lamp_o     : out   std_logic;    -- Config Interface -------------------------------------------------------    cfg_clk_i  : in    std_logic;    cfg_data_i : in    std_logic;    start_o    : out   std_logic;    mode_o     : out   std_logic;    done_o     : out   std_logic;    detached_i : in    std_logic;    -- Asynchronous RAM Interface ---------------------------------------------    ram_addr_o : out   std_logic_vector(15 downto 0);    ram_data_b : out   std_logic_vector( 7 downto 0);    ram_ce_no  : out   std_logic_vector( 3 downto 0);    ram_oe_no  : out   std_logic;    ram_we_no  : out   std_logic  );end ram_loader;library ieee;use ieee.numeric_std.all;architecture rtl of ram_loader is  signal addr_q     : unsigned(17 downto 0);  signal inc_addr_s : boolean;  signal shift_dat_q : std_logic_vector(7 downto 0);  signal ser_dat_q   : std_logic_vector(7 downto 0);  signal bit_q       : unsigned(2 downto 0);  signal bit_ovfl_q  : boolean;  type fsm_t is (IDLE,                 WE_ON,                 WE_OFF,                 INC_ADDR1, INC_ADDR2,                 FINISHED);  signal fsm_s,         fsm_q  : fsm_t;  signal done_q          : std_logic;  signal done_s          : boolean;  signal mode_q,         mode_s          : std_logic;  signal ram_we_n_q,         ram_we_n_s  : std_logic;  signal ram_ce_n_q,         ram_ce_n_s  : std_logic_vector(3 downto 0);  type start_fsm_t is (WAIT_DETACH,                       CHECK_NO_DONE,                       WAIT_DONE);  signal start_fsm_s,         start_fsm_q  : start_fsm_t;  signal start_s,         start_q         : std_logic;  signal enable_s,         enable_q        : boolean;begin  -----------------------------------------------------------------------------  -- Process seq  --  -- Purpose:  --   Implements the sequential elements clocked with cfg_clk_i.  --  seq: process (cfg_clk_i, reset_i)  begin    if reset_i = '0' then      addr_q      <= (others => '0');      shift_dat_q <= (others => '0');      ser_dat_q   <= (others => '0');      bit_q       <= (others => '0');      bit_ovfl_q  <= false;      fsm_q       <= IDLE;      ram_we_n_q  <= '1';      ram_ce_n_q  <= (others => '1');      done_q      <= '0';      mode_q      <= '0';    elsif cfg_clk_i'event and cfg_clk_i = '1' then      if inc_addr_s then        addr_q <= addr_q + 1;      end if;      if enable_q then        bit_q      <= bit_q + 1;        bit_ovfl_q <= bit_q = 7;        shift_dat_q(0) <= cfg_data_i;        shift_dat_q(7 downto 1) <= shift_dat_q(6 downto 0);      end if;      -- update register when 8 serial bits have been shifted in      if bit_ovfl_q then        ser_dat_q <= shift_dat_q;      end if;      fsm_q <= fsm_s;      ram_we_n_q <= ram_we_n_s;      ram_ce_n_q <= ram_ce_n_s;      -- done only settable once      if done_s then        done_q <= '1';      end if;      mode_q <= mode_s;    end if;  end process seq;  --  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------  -- Process fsm  --  -- Purpose:  --   Implements the combinational logic of the RAM loader FSM.  --  fsm: process (fsm_q,                bit_ovfl_q,                start_q,                addr_q)  begin    -- default assignments    inc_addr_s      <= false;    ram_we_n_s      <= '1';    done_s          <= false;    fsm_s           <= IDLE;    lamp_o          <= '1';    mode_s          <= '0';    case fsm_q is      when IDLE =>        lamp_o <= '0';        if start_q = '1' then          if bit_ovfl_q then            fsm_s <= WE_ON;          end if;        end if;      when WE_ON =>        ram_we_n_s <= '0';        fsm_s      <= WE_OFF;      when WE_OFF =>        fsm_s <= INC_ADDR1;      when INC_ADDR1 =>        fsm_s      <= INC_ADDR2;      when INC_ADDR2 =>        if addr_q = "001111111111111111" then  -- load only 64k          fsm_s <= FINISHED;          done_s <= true;          mode_s <= '1';        else          inc_addr_s <= true;          fsm_s      <= IDLE;        end if;      when FINISHED =>        fsm_s  <= FINISHED;        lamp_o <= '1';        mode_s <= '1';      when others =>    end case;  end process fsm;  --  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------  -- Process ce_gen  --  -- Purpose:  --   Generates the four CE signals for the external RAM chips.  --  ce_gen: process (addr_q)  begin    ram_ce_n_s <= (others => '1');    ram_ce_n_s(to_integer(addr_q(17 downto 16))) <= '0';  end process ce_gen;  --  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------  -- Process start_seq  --  -- Purpose:  --   Implements the sequential elements clocked with clk_i.  --  start_seq: process (clk_i, reset_i)  begin    if reset_i = '0' then      start_fsm_q <= WAIT_DETACH;      start_q     <= '0';      enable_q    <= false;    elsif clk_i'event and clk_i = '1' then      start_fsm_q <= start_fsm_s;      enable_q    <= enable_s;      start_q     <= start_s;    end if;  end process start_seq;  --  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------  -- Process start_comb  --  -- Purpose:  --   Implements the combinational logic of the start FSM.  --  start_comb: process (start_fsm_q,                       detached_i,                       done_q,                       enable_q,                       start_q)  begin    -- default assignments    start_fsm_s <= WAIT_DETACH;    enable_s    <= enable_q;    start_s     <= start_q;    case start_fsm_q is      -- Wait for detached_i to become '1'      -- This state is entered/left twice:      -- 1. after reset to start the data download      -- 2. after data download to start the next configuration cycle      when WAIT_DETACH =>        if detached_i = '1' then          start_fsm_s <= CHECK_NO_DONE;          enable_s    <= true;          start_s     <= '1';        else          start_fsm_s <= WAIT_DETACH;        end if;      -- Wait until done_q is '0'      -- This ensures that the FSM stalls when it has started the configuration      -- download. There must be no further action in this case.      when CHECK_NO_DONE =>        if done_q = '0' then          start_fsm_s <= WAIT_DONE;        else          start_fsm_s <= CHECK_NO_DONE;        end if;      -- Wait until done_q is '1'      -- done_q is the signal that the main FSM has finished its work. We      -- need to start the configuration download.      when WAIT_DONE =>        if done_q = '1' then          start_fsm_s <= WAIT_DETACH;          enable_s    <= false;          start_s     <= '0';        else          start_fsm_s <= WAIT_DONE;        end if;      when others =>        null;    end case;  end process start_comb;  --  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------  -- Output Mapping  -----------------------------------------------------------------------------  start_o    <= start_q;  mode_o     <= mode_q;  done_o     <=   done_q                when start_q = '1' else                  '1';  ram_addr_o <= std_logic_vector(addr_q(15 downto 0));  ram_data_b <= ser_dat_q;  ram_oe_no  <= '1';  ram_ce_no  <= ram_ce_n_q;  ram_we_no  <= ram_we_n_q;end rtl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -