diff options
Diffstat (limited to 'opencores/spi_boot/rtl/vhdl/sample')
| -rw-r--r-- | opencores/spi_boot/rtl/vhdl/sample/CVS/Entries | 3 | ||||
| -rw-r--r-- | opencores/spi_boot/rtl/vhdl/sample/CVS/Repository | 1 | ||||
| -rw-r--r-- | opencores/spi_boot/rtl/vhdl/sample/CVS/Root | 1 | ||||
| -rw-r--r-- | opencores/spi_boot/rtl/vhdl/sample/CVS/Template | 0 | ||||
| -rw-r--r-- | opencores/spi_boot/rtl/vhdl/sample/ram_loader-c.vhd | 10 | ||||
| -rw-r--r-- | opencores/spi_boot/rtl/vhdl/sample/ram_loader.vhd | 355 | 
6 files changed, 370 insertions, 0 deletions
| diff --git a/opencores/spi_boot/rtl/vhdl/sample/CVS/Entries b/opencores/spi_boot/rtl/vhdl/sample/CVS/Entries new file mode 100644 index 000000000..552a7baad --- /dev/null +++ b/opencores/spi_boot/rtl/vhdl/sample/CVS/Entries @@ -0,0 +1,3 @@ +/ram_loader-c.vhd/1.1/Sun Apr 10 18:02:32 2005// +/ram_loader.vhd/1.2/Sun Apr 10 17:17:23 2005// +D diff --git a/opencores/spi_boot/rtl/vhdl/sample/CVS/Repository b/opencores/spi_boot/rtl/vhdl/sample/CVS/Repository new file mode 100644 index 000000000..026a73983 --- /dev/null +++ b/opencores/spi_boot/rtl/vhdl/sample/CVS/Repository @@ -0,0 +1 @@ +spi_boot/rtl/vhdl/sample diff --git a/opencores/spi_boot/rtl/vhdl/sample/CVS/Root b/opencores/spi_boot/rtl/vhdl/sample/CVS/Root new file mode 100644 index 000000000..44b2aa23b --- /dev/null +++ b/opencores/spi_boot/rtl/vhdl/sample/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.opencores.org:/cvsroot/anonymous diff --git a/opencores/spi_boot/rtl/vhdl/sample/CVS/Template b/opencores/spi_boot/rtl/vhdl/sample/CVS/Template new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/opencores/spi_boot/rtl/vhdl/sample/CVS/Template diff --git a/opencores/spi_boot/rtl/vhdl/sample/ram_loader-c.vhd b/opencores/spi_boot/rtl/vhdl/sample/ram_loader-c.vhd new file mode 100644 index 000000000..8b26c4d57 --- /dev/null +++ b/opencores/spi_boot/rtl/vhdl/sample/ram_loader-c.vhd @@ -0,0 +1,10 @@ +------------------------------------------------------------------------------- +-- $Id: ram_loader-c.vhd,v 1.1 2005/04/10 18:02:32 arniml Exp $ +------------------------------------------------------------------------------- + +configuration ram_loader_rtl_c0 of ram_loader is + +  for rtl +  end for; + +end ram_loader_rtl_c0; diff --git a/opencores/spi_boot/rtl/vhdl/sample/ram_loader.vhd b/opencores/spi_boot/rtl/vhdl/sample/ram_loader.vhd new file mode 100644 index 000000000..c604876d7 --- /dev/null +++ b/opencores/spi_boot/rtl/vhdl/sample/ram_loader.vhd @@ -0,0 +1,355 @@ +------------------------------------------------------------------------------- +-- +-- SD/MMC Bootloader +-- Sample client for loading an image to asynchronous SRAM +-- +-- $Id: ram_loader.vhd,v 1.2 2005/04/10 17:17:23 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; +    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; | 
