OpenCores
URL https://opencores.org/ocsvn/spi_boot/spi_boot/trunk

Subversion Repositories spi_boot

[/] [spi_boot/] [trunk/] [rtl/] [vhdl/] [sample/] [ram_loader.vhd] - Rev 19

Go to most recent revision | Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
--
-- SD/MMC Bootloader
-- Sample client for loading an image to asynchronous SRAM
--
-- $Id: ram_loader.vhd,v 1.1 2005-02-18 20:49:00 arniml Exp $
--
-- 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;
    -- 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 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);
 
  signal start_q         : std_logic;
  signal trigger_start_s,
         trigger_start_q : boolean;
  signal seen_trigger_q  : boolean;
  signal start_cnt_q     : unsigned(7 downto 0);
  signal done_q          : std_logic;
  signal done_s          : boolean;
  signal mode_q,
         mode_s          : std_logic;
  signal enable_q        : boolean;
 
begin
 
  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';
      trigger_start_q <= false;
 
    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;
 
      if done_s then
        done_q <= '1';
      end if;
 
      trigger_start_q <= trigger_start_s;
 
    end if;
  end process seq;
 
 
  start: process (clk_i, reset_i)
    variable trigger_start_v : boolean;
  begin
    if reset_i = '0' then
      start_cnt_q   <= (others => '0');
      start_q       <= '0';
      mode_q        <= '0';
      enable_q      <= false;
      seen_trigger_q <= false;
 
    elsif clk_i'event and clk_i = '1' then
      trigger_start_v := not seen_trigger_q and trigger_start_q;
 
      if trigger_start_q then
        seen_trigger_q <= true;
      end if;
 
      if trigger_start_v then
        start_cnt_q <= (others => '0');
      elsif start_q = '0' then
        start_cnt_q <= start_cnt_q + 1;
      end if;
 
      if trigger_start_v then
        start_q     <= '0';
      elsif start_cnt_q = "11111111" then
        start_q     <= '1';
        enable_q    <= true;
        if start_q = '0' then
          mode_q    <= mode_s;
        end if;
      end if;
 
    end if;
  end process start;
 
 
  fsm: process (fsm_q,
                bit_ovfl_q,
                start_q,
                addr_q)
  begin
    -- default assignments
    inc_addr_s      <= false;
    ram_we_n_s      <= '1';
    trigger_start_s <= false;
    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;
          trigger_start_s <= true;
          done_s <= true;
        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;
 
  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;
 
  -----------------------------------------------------------------------------
  -- 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;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.