aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp2/opencores/spi_boot/rtl
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2020-01-23 16:10:22 -0800
committerMartin Braun <martin.braun@ettus.com>2020-01-28 09:35:36 -0800
commitbafa9d95453387814ef25e6b6256ba8db2df612f (patch)
tree39ba24b5b67072d354775272e687796bb511848d /fpga/usrp2/opencores/spi_boot/rtl
parent3075b981503002df3115d5f1d0b97d2619ba30f2 (diff)
downloaduhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.gz
uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.tar.bz2
uhd-bafa9d95453387814ef25e6b6256ba8db2df612f.zip
Merge FPGA repository back into UHD repository
The FPGA codebase was removed from the UHD repository in 2014 to reduce the size of the repository. However, over the last half-decade, the split between the repositories has proven more burdensome than it has been helpful. By merging the FPGA code back, it will be possible to create atomic commits that touch both FPGA and UHD codebases. Continuous integration testing is also simplified by merging the repositories, because it was previously difficult to automatically derive the correct UHD branch when testing a feature branch on the FPGA repository. This commit also updates the license files and paths therein. We are therefore merging the repositories again. Future development for FPGA code will happen in the same repository as the UHD host code and MPM code. == Original Codebase and Rebasing == The original FPGA repository will be hosted for the foreseeable future at its original local location: https://github.com/EttusResearch/fpga/ It can be used for bisecting, reference, and a more detailed history. The final commit from said repository to be merged here is 05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as v4.0.0.0-pre-uhd-merge. If you have changes in the FPGA repository that you want to rebase onto the UHD repository, simply run the following commands: - Create a directory to store patches (this should be an empty directory): mkdir ~/patches - Now make sure that your FPGA codebase is based on the same state as the code that was merged: cd src/fpga # Or wherever your FPGA code is stored git rebase v4.0.0.0-pre-uhd-merge Note: The rebase command may look slightly different depending on what exactly you're trying to rebase. - Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge: git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches Note: Make sure that only patches are stored in your output directory. It should otherwise be empty. Make sure that you picked the correct range of commits, and only commits you wanted to rebase were exported as patch files. - Go to the UHD repository and apply the patches: cd src/uhd # Or wherever your UHD repository is stored git am --directory fpga ~/patches/* rm -rf ~/patches # This is for cleanup == Contributors == The following people have contributed mainly to these files (this list is not complete): Co-authored-by: Alex Williams <alex.williams@ni.com> Co-authored-by: Andrej Rode <andrej.rode@ettus.com> Co-authored-by: Ashish Chaudhari <ashish@ettus.com> Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com> Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com> Co-authored-by: Daniel Jepson <daniel.jepson@ni.com> Co-authored-by: Derek Kozel <derek.kozel@ettus.com> Co-authored-by: EJ Kreinar <ej@he360.com> Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com> Co-authored-by: Ian Buckley <ian.buckley@gmail.com> Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com> Co-authored-by: Jon Kiser <jon.kiser@ni.com> Co-authored-by: Josh Blum <josh@joshknows.com> Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com> Co-authored-by: Martin Braun <martin.braun@ettus.com> Co-authored-by: Matt Ettus <matt@ettus.com> Co-authored-by: Michael West <michael.west@ettus.com> Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com> Co-authored-by: Nick Foster <nick@ettus.com> Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com> Co-authored-by: Paul Butler <paul.butler@ni.com> Co-authored-by: Paul David <paul.david@ettus.com> Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com> Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com> Co-authored-by: Sylvain Munaut <tnt@246tNt.com> Co-authored-by: Trung Tran <trung.tran@ettus.com> Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com> Co-authored-by: Wade Fife <wade.fife@ettus.com>
Diffstat (limited to 'fpga/usrp2/opencores/spi_boot/rtl')
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-e.vhd91
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-full-a.vhd164
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-full-c.vhd19
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-minimal-a.vhd164
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-minimal-c.vhd19
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-mmc-a.vhd164
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-mmc-c.vhd19
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-sd-a.vhd164
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-sd-c.vhd19
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/sample/ram_loader-c.vhd10
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/sample/ram_loader.vhd355
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot-c.vhd27
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot.vhd979
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot_pack-p.vhd54
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_counter-c.vhd14
-rw-r--r--fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_counter.vhd118
16 files changed, 2380 insertions, 0 deletions
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-e.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-e.vhd
new file mode 100644
index 000000000..0bdd05aff
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-e.vhd
@@ -0,0 +1,91 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+-- Chip toplevel
+--
+-- $Id: chip-e.vhd,v 1.3 2005/04/07 20:44: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 chip is
+
+ port (
+ -- System Interface -------------------------------------------------------
+ clk_i : in std_logic;
+ reset_i : in std_logic;
+ set_sel_n_i : in std_logic_vector(3 downto 0);
+ -- SD Card Interface ------------------------------------------------------
+ spi_clk_o : out std_logic;
+ spi_cs_n_o : out std_logic;
+ spi_data_in_i : in std_logic;
+ spi_data_out_o : out std_logic;
+ -- FPGA Configuration Interface -------------------------------------------
+ start_i : in std_logic;
+ mode_i : in std_logic;
+ config_n_o : out std_logic;
+ detached_o : out std_logic;
+ cfg_init_n_i : in std_logic;
+ cfg_done_i : in std_logic;
+ dat_done_i : in std_logic;
+ cfg_clk_o : out std_logic;
+ cfg_dat_o : out std_logic
+ );
+
+end chip;
+
+
+-------------------------------------------------------------------------------
+-- File History:
+--
+-- $Log: chip-e.vhd,v $
+-- Revision 1.3 2005/04/07 20:44:23 arniml
+-- add new port detached_o
+--
+-- Revision 1.2 2005/03/08 22:07:11 arniml
+-- added set selection
+--
+-- Revision 1.1 2005/02/08 20:41:30 arniml
+-- initial check-in
+--
+-------------------------------------------------------------------------------
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-full-a.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-full-a.vhd
new file mode 100644
index 000000000..e43ecb3c4
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-full-a.vhd
@@ -0,0 +1,164 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+-- Chip toplevel design with full feature set
+--
+-- $Id: chip-full-a.vhd,v 1.6 2005/04/07 20:44: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;
+
+
+architecture full of chip is
+
+ component spi_boot
+ generic (
+ width_set_sel_g : integer := 4;
+ width_bit_cnt_g : integer := 6;
+ width_img_cnt_g : integer := 2;
+ num_bits_per_img_g : integer := 18;
+ sd_init_g : integer := 0;
+ mmc_compat_clk_div_g : integer := 0;
+ width_mmc_clk_div_g : integer := 0;
+ reset_level_g : integer := 0
+ );
+ port (
+ clk_i : in std_logic;
+ reset_i : in std_logic;
+ set_sel_i : in std_logic_vector(width_set_sel_g-1 downto 0);
+ spi_clk_o : out std_logic;
+ spi_cs_n_o : out std_logic;
+ spi_data_in_i : in std_logic;
+ spi_data_out_o : out std_logic;
+ spi_en_outs_o : out std_logic;
+ start_i : in std_logic;
+ mode_i : in std_logic;
+ config_n_o : out std_logic;
+ detached_o : out std_logic;
+ cfg_init_n_i : in std_logic;
+ cfg_done_i : in std_logic;
+ dat_done_i : in std_logic;
+ cfg_clk_o : out std_logic;
+ cfg_dat_o : out std_logic
+ );
+ end component;
+
+ signal spi_clk_s : std_logic;
+ signal spi_cs_n_s : std_logic;
+ signal spi_data_out_s : std_logic;
+ signal spi_en_outs_s : std_logic;
+
+ signal set_sel_s : std_logic_vector(3 downto 0);
+
+begin
+
+ set_sel_s <= not set_sel_n_i;
+
+ spi_boot_b : spi_boot
+ generic map (
+ width_set_sel_g => 4, -- 16 sets
+ width_bit_cnt_g => 12, -- 512 bytes per block
+ width_img_cnt_g => 2, -- 4 images
+ num_bits_per_img_g => 18, -- 256 kByte per image
+ sd_init_g => 1, -- use SD specific initialization
+ mmc_compat_clk_div_g => 13, -- MMC compat 400 kHz > 10 MHz / (13*2)
+ width_mmc_clk_div_g => 4 -- need 5 bits for MMC compat divider
+ )
+ port map (
+ clk_i => clk_i,
+ reset_i => reset_i,
+ set_sel_i => set_sel_s,
+ spi_clk_o => spi_clk_s,
+ spi_cs_n_o => spi_cs_n_s,
+ spi_data_in_i => spi_data_in_i,
+ spi_data_out_o => spi_data_out_s,
+ spi_en_outs_o => spi_en_outs_s,
+ start_i => start_i,
+ mode_i => mode_i,
+ config_n_o => config_n_o,
+ detached_o => detached_o,
+ cfg_init_n_i => cfg_init_n_i,
+ cfg_done_i => cfg_done_i,
+ dat_done_i => dat_done_i,
+ cfg_clk_o => cfg_clk_o,
+ cfg_dat_o => cfg_dat_o
+ );
+
+ -----------------------------------------------------------------------------
+ -- Three state drivers for SPI outputs.
+ -----------------------------------------------------------------------------
+ spi_clk_o <= spi_clk_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+ spi_cs_n_o <= spi_cs_n_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+ spi_data_out_o <= spi_data_out_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+
+end full;
+
+
+-------------------------------------------------------------------------------
+-- File History:
+--
+-- $Log: chip-full-a.vhd,v $
+-- Revision 1.6 2005/04/07 20:44:23 arniml
+-- add new port detached_o
+--
+-- Revision 1.5 2005/03/09 19:48:34 arniml
+-- invert level of set_sel input
+--
+-- Revision 1.4 2005/03/08 22:07:12 arniml
+-- added set selection
+--
+-- Revision 1.3 2005/02/18 06:42:11 arniml
+-- clarify wording for images
+--
+-- Revision 1.2 2005/02/16 18:54:37 arniml
+-- added tri-state drivers for spi outputs
+--
+-- Revision 1.1 2005/02/08 20:41:31 arniml
+-- initial check-in
+--
+-------------------------------------------------------------------------------
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-full-c.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-full-c.vhd
new file mode 100644
index 000000000..da88552c4
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-full-c.vhd
@@ -0,0 +1,19 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+--
+-- $Id: chip-full-c.vhd,v 1.1 2005/02/08 20:41:31 arniml Exp $
+--
+-------------------------------------------------------------------------------
+
+configuration chip_full_c0 of chip is
+
+ for full
+
+ for spi_boot_b : spi_boot
+ use configuration work.spi_boot_rtl_c0;
+ end for;
+
+ end for;
+
+end chip_full_c0;
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-minimal-a.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-minimal-a.vhd
new file mode 100644
index 000000000..090d0b79c
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-minimal-a.vhd
@@ -0,0 +1,164 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+-- Chip toplevel design with minimal feature set
+--
+-- $Id: chip-minimal-a.vhd,v 1.6 2005/04/07 20:44: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;
+
+
+architecture minimal of chip is
+
+ component spi_boot
+ generic (
+ width_set_sel_g : integer := 4;
+ width_bit_cnt_g : integer := 6;
+ width_img_cnt_g : integer := 2;
+ num_bits_per_img_g : integer := 18;
+ sd_init_g : integer := 0;
+ mmc_compat_clk_div_g : integer := 0;
+ width_mmc_clk_div_g : integer := 0;
+ reset_level_g : integer := 0
+ );
+ port (
+ clk_i : in std_logic;
+ reset_i : in std_logic;
+ set_sel_i : in std_logic_vector(width_set_sel_g-1 downto 0);
+ spi_clk_o : out std_logic;
+ spi_cs_n_o : out std_logic;
+ spi_data_in_i : in std_logic;
+ spi_data_out_o : out std_logic;
+ spi_en_outs_o : out std_logic;
+ start_i : in std_logic;
+ mode_i : in std_logic;
+ config_n_o : out std_logic;
+ detached_o : out std_logic;
+ cfg_init_n_i : in std_logic;
+ cfg_done_i : in std_logic;
+ dat_done_i : in std_logic;
+ cfg_clk_o : out std_logic;
+ cfg_dat_o : out std_logic
+ );
+ end component;
+
+ signal spi_clk_s : std_logic;
+ signal spi_cs_n_s : std_logic;
+ signal spi_data_out_s : std_logic;
+ signal spi_en_outs_s : std_logic;
+
+ signal set_sel_s : std_logic_vector(3 downto 0);
+
+begin
+
+ set_sel_s <= not set_sel_n_i;
+
+ spi_boot_b : spi_boot
+ generic map (
+ width_set_sel_g => 4, -- 16 sets
+ width_bit_cnt_g => 6, -- 8 bytes per block
+ width_img_cnt_g => 2, -- 4 images
+ num_bits_per_img_g => 18, -- 256 kByte per image
+ sd_init_g => 0, -- no SD specific initialization
+ mmc_compat_clk_div_g => 0, -- no MMC compatibility
+ width_mmc_clk_div_g => 0 -- no MMC compatibility
+ )
+ port map (
+ clk_i => clk_i,
+ reset_i => reset_i,
+ set_sel_i => set_sel_s,
+ spi_clk_o => spi_clk_s,
+ spi_cs_n_o => spi_cs_n_s,
+ spi_data_in_i => spi_data_in_i,
+ spi_data_out_o => spi_data_out_s,
+ spi_en_outs_o => spi_en_outs_s,
+ start_i => start_i,
+ mode_i => mode_i,
+ config_n_o => config_n_o,
+ detached_o => detached_o,
+ cfg_init_n_i => cfg_init_n_i,
+ cfg_done_i => cfg_done_i,
+ dat_done_i => dat_done_i,
+ cfg_clk_o => cfg_clk_o,
+ cfg_dat_o => cfg_dat_o
+ );
+
+ -----------------------------------------------------------------------------
+ -- Three state drivers for SPI outputs.
+ -----------------------------------------------------------------------------
+ spi_clk_o <= spi_clk_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+ spi_cs_n_o <= spi_cs_n_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+ spi_data_out_o <= spi_data_out_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+
+end minimal;
+
+
+-------------------------------------------------------------------------------
+-- File History:
+--
+-- $Log: chip-minimal-a.vhd,v $
+-- Revision 1.6 2005/04/07 20:44:23 arniml
+-- add new port detached_o
+--
+-- Revision 1.5 2005/03/09 19:48:34 arniml
+-- invert level of set_sel input
+--
+-- Revision 1.4 2005/03/08 22:07:12 arniml
+-- added set selection
+--
+-- Revision 1.3 2005/02/18 06:42:12 arniml
+-- clarify wording for images
+--
+-- Revision 1.2 2005/02/16 18:54:39 arniml
+-- added tri-state drivers for spi outputs
+--
+-- Revision 1.1 2005/02/08 20:41:31 arniml
+-- initial check-in
+--
+-------------------------------------------------------------------------------
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-minimal-c.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-minimal-c.vhd
new file mode 100644
index 000000000..5547747b2
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-minimal-c.vhd
@@ -0,0 +1,19 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+--
+-- $Id: chip-minimal-c.vhd,v 1.1 2005/02/08 20:41:32 arniml Exp $
+--
+-------------------------------------------------------------------------------
+
+configuration chip_minimal_c0 of chip is
+
+ for minimal
+
+ for spi_boot_b : spi_boot
+ use configuration work.spi_boot_rtl_c0;
+ end for;
+
+ end for;
+
+end chip_minimal_c0;
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-mmc-a.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-mmc-a.vhd
new file mode 100644
index 000000000..cef42d268
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-mmc-a.vhd
@@ -0,0 +1,164 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+-- Chip toplevel design with MMC feature set
+--
+-- $Id: chip-mmc-a.vhd,v 1.6 2005/04/07 20:44: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;
+
+
+architecture mmc of chip is
+
+ component spi_boot
+ generic (
+ width_set_sel_g : integer := 4;
+ width_bit_cnt_g : integer := 6;
+ width_img_cnt_g : integer := 2;
+ num_bits_per_img_g : integer := 18;
+ sd_init_g : integer := 0;
+ mmc_compat_clk_div_g : integer := 0;
+ width_mmc_clk_div_g : integer := 0;
+ reset_level_g : integer := 0
+ );
+ port (
+ clk_i : in std_logic;
+ reset_i : in std_logic;
+ set_sel_i : in std_logic_vector(width_set_sel_g-1 downto 0);
+ spi_clk_o : out std_logic;
+ spi_cs_n_o : out std_logic;
+ spi_data_in_i : in std_logic;
+ spi_data_out_o : out std_logic;
+ spi_en_outs_o : out std_logic;
+ start_i : in std_logic;
+ mode_i : in std_logic;
+ config_n_o : out std_logic;
+ detached_o : out std_logic;
+ cfg_init_n_i : in std_logic;
+ cfg_done_i : in std_logic;
+ dat_done_i : in std_logic;
+ cfg_clk_o : out std_logic;
+ cfg_dat_o : out std_logic
+ );
+ end component;
+
+ signal spi_clk_s : std_logic;
+ signal spi_cs_n_s : std_logic;
+ signal spi_data_out_s : std_logic;
+ signal spi_en_outs_s : std_logic;
+
+ signal set_sel_s : std_logic_vector(3 downto 0);
+
+begin
+
+ set_sel_s <= not set_sel_n_i;
+
+ spi_boot_b : spi_boot
+ generic map (
+ width_set_sel_g => 4, -- 16 sets
+ width_bit_cnt_g => 12, -- 512 bytes per block
+ width_img_cnt_g => 2, -- 4 images
+ num_bits_per_img_g => 18, -- 256 kByte per image
+ sd_init_g => 0, -- no SD specific initialization
+ mmc_compat_clk_div_g => 13, -- MMC compat 400 kHz > 10 MHz / (13*2)
+ width_mmc_clk_div_g => 4 -- need 5 bits for MMC compat divider
+ )
+ port map (
+ clk_i => clk_i,
+ reset_i => reset_i,
+ set_sel_i => set_sel_s,
+ spi_clk_o => spi_clk_s,
+ spi_cs_n_o => spi_cs_n_s,
+ spi_data_in_i => spi_data_in_i,
+ spi_data_out_o => spi_data_out_s,
+ spi_en_outs_o => spi_en_outs_s,
+ start_i => start_i,
+ mode_i => mode_i,
+ config_n_o => config_n_o,
+ detached_o => detached_o,
+ cfg_init_n_i => cfg_init_n_i,
+ cfg_done_i => cfg_done_i,
+ dat_done_i => dat_done_i,
+ cfg_clk_o => cfg_clk_o,
+ cfg_dat_o => cfg_dat_o
+ );
+
+ -----------------------------------------------------------------------------
+ -- Three state drivers for SPI outputs.
+ -----------------------------------------------------------------------------
+ spi_clk_o <= spi_clk_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+ spi_cs_n_o <= spi_cs_n_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+ spi_data_out_o <= spi_data_out_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+
+end mmc;
+
+
+-------------------------------------------------------------------------------
+-- File History:
+--
+-- $Log: chip-mmc-a.vhd,v $
+-- Revision 1.6 2005/04/07 20:44:23 arniml
+-- add new port detached_o
+--
+-- Revision 1.5 2005/03/09 19:48:34 arniml
+-- invert level of set_sel input
+--
+-- Revision 1.4 2005/03/08 22:07:12 arniml
+-- added set selection
+--
+-- Revision 1.3 2005/02/18 06:42:13 arniml
+-- clarify wording for images
+--
+-- Revision 1.2 2005/02/16 18:54:39 arniml
+-- added tri-state drivers for spi outputs
+--
+-- Revision 1.1 2005/02/08 20:41:32 arniml
+-- initial check-in
+--
+-------------------------------------------------------------------------------
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-mmc-c.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-mmc-c.vhd
new file mode 100644
index 000000000..6131013e4
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-mmc-c.vhd
@@ -0,0 +1,19 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+--
+-- $Id: chip-mmc-c.vhd,v 1.1 2005/02/08 20:41:32 arniml Exp $
+--
+-------------------------------------------------------------------------------
+
+configuration chip_mmc_c0 of chip is
+
+ for mmc
+
+ for spi_boot_b : spi_boot
+ use configuration work.spi_boot_rtl_c0;
+ end for;
+
+ end for;
+
+end chip_mmc_c0;
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-sd-a.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-sd-a.vhd
new file mode 100644
index 000000000..c955a5f3a
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-sd-a.vhd
@@ -0,0 +1,164 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+-- Chip toplevel design with SD feature set
+--
+-- $Id: chip-sd-a.vhd,v 1.6 2005/04/07 20:44: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;
+
+
+architecture sd of chip is
+
+ component spi_boot
+ generic (
+ width_set_sel_g : integer := 4;
+ width_bit_cnt_g : integer := 6;
+ width_img_cnt_g : integer := 2;
+ num_bits_per_img_g : integer := 18;
+ sd_init_g : integer := 0;
+ mmc_compat_clk_div_g : integer := 0;
+ width_mmc_clk_div_g : integer := 0;
+ reset_level_g : integer := 0
+ );
+ port (
+ clk_i : in std_logic;
+ reset_i : in std_logic;
+ set_sel_i : in std_logic_vector(width_set_sel_g-1 downto 0);
+ spi_clk_o : out std_logic;
+ spi_cs_n_o : out std_logic;
+ spi_data_in_i : in std_logic;
+ spi_data_out_o : out std_logic;
+ spi_en_outs_o : out std_logic;
+ start_i : in std_logic;
+ mode_i : in std_logic;
+ config_n_o : out std_logic;
+ detached_o : out std_logic;
+ cfg_init_n_i : in std_logic;
+ cfg_done_i : in std_logic;
+ dat_done_i : in std_logic;
+ cfg_clk_o : out std_logic;
+ cfg_dat_o : out std_logic
+ );
+ end component;
+
+ signal spi_clk_s : std_logic;
+ signal spi_cs_n_s : std_logic;
+ signal spi_data_out_s : std_logic;
+ signal spi_en_outs_s : std_logic;
+
+ signal set_sel_s : std_logic_vector(3 downto 0);
+
+begin
+
+ set_sel_s <= not set_sel_n_i;
+
+ spi_boot_b : spi_boot
+ generic map (
+ width_set_sel_g => 4, -- 16 sets
+ width_bit_cnt_g => 12, -- 512 bytes per block
+ width_img_cnt_g => 2, -- 4 images
+ num_bits_per_img_g => 18, -- 256 kByte per image
+ sd_init_g => 1, -- SD specific initialization
+ mmc_compat_clk_div_g => 0, -- no MMC compatibility
+ width_mmc_clk_div_g => 0 -- no MMC compatibility
+ )
+ port map (
+ clk_i => clk_i,
+ reset_i => reset_i,
+ set_sel_i => set_sel_s,
+ spi_clk_o => spi_clk_s,
+ spi_cs_n_o => spi_cs_n_s,
+ spi_data_in_i => spi_data_in_i,
+ spi_data_out_o => spi_data_out_s,
+ spi_en_outs_o => spi_en_outs_s,
+ start_i => start_i,
+ mode_i => mode_i,
+ config_n_o => config_n_o,
+ detached_o => detached_o,
+ cfg_init_n_i => cfg_init_n_i,
+ cfg_done_i => cfg_done_i,
+ dat_done_i => dat_done_i,
+ cfg_clk_o => cfg_clk_o,
+ cfg_dat_o => cfg_dat_o
+ );
+
+ -----------------------------------------------------------------------------
+ -- Three state drivers for SPI outputs.
+ -----------------------------------------------------------------------------
+ spi_clk_o <= spi_clk_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+ spi_cs_n_o <= spi_cs_n_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+ spi_data_out_o <= spi_data_out_s
+ when spi_en_outs_s = '1' else
+ 'Z';
+
+end sd;
+
+
+-------------------------------------------------------------------------------
+-- File History:
+--
+-- $Log: chip-sd-a.vhd,v $
+-- Revision 1.6 2005/04/07 20:44:23 arniml
+-- add new port detached_o
+--
+-- Revision 1.5 2005/03/09 19:48:34 arniml
+-- invert level of set_sel input
+--
+-- Revision 1.4 2005/03/08 22:07:12 arniml
+-- added set selection
+--
+-- Revision 1.3 2005/02/18 06:42:14 arniml
+-- clarify wording for images
+--
+-- Revision 1.2 2005/02/16 18:54:39 arniml
+-- added tri-state drivers for spi outputs
+--
+-- Revision 1.1 2005/02/08 20:41:32 arniml
+-- initial check-in
+--
+-------------------------------------------------------------------------------
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-sd-c.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-sd-c.vhd
new file mode 100644
index 000000000..91e41ddfb
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/chip-sd-c.vhd
@@ -0,0 +1,19 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+--
+-- $Id: chip-sd-c.vhd,v 1.1 2005/02/08 20:41:33 arniml Exp $
+--
+-------------------------------------------------------------------------------
+
+configuration chip_sd_c0 of chip is
+
+ for sd
+
+ for spi_boot_b : spi_boot
+ use configuration work.spi_boot_rtl_c0;
+ end for;
+
+ end for;
+
+end chip_sd_c0;
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/sample/ram_loader-c.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/sample/ram_loader-c.vhd
new file mode 100644
index 000000000..8b26c4d57
--- /dev/null
+++ b/fpga/usrp2/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/fpga/usrp2/opencores/spi_boot/rtl/vhdl/sample/ram_loader.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/sample/ram_loader.vhd
new file mode 100644
index 000000000..c604876d7
--- /dev/null
+++ b/fpga/usrp2/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;
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot-c.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot-c.vhd
new file mode 100644
index 000000000..6f11ed34b
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot-c.vhd
@@ -0,0 +1,27 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+--
+-- $Id: spi_boot-c.vhd,v 1.2 2005/02/18 06:42:11 arniml Exp $
+--
+-------------------------------------------------------------------------------
+
+configuration spi_boot_rtl_c0 of spi_boot is
+
+ for rtl
+
+ for img_cnt
+ for img_cnt_b : spi_counter
+ use configuration work.spi_counter_rtl_c0;
+ end for;
+ end for;
+
+ for mmc_cnt
+ for mmc_cnt_b : spi_counter
+ use configuration work.spi_counter_rtl_c0;
+ end for;
+ end for;
+
+ end for;
+
+end spi_boot_rtl_c0;
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot.vhd
new file mode 100644
index 000000000..3d2b81da7
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot.vhd
@@ -0,0 +1,979 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+--
+-- $Id: spi_boot.vhd,v 1.9 2007/02/25 18:24:12 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 spi_boot is
+
+ generic (
+ -- width of set selection
+ width_set_sel_g : integer := 4;
+ -- width of bit counter: minimum 6, maximum 12
+ width_bit_cnt_g : integer := 6;
+ -- width of image counter: minimum 0, maximum n
+ width_img_cnt_g : integer := 2;
+ -- number of bits required to address one image
+ num_bits_per_img_g : integer := 18;
+ -- SD specific initialization
+ sd_init_g : integer := 0;
+ -- clock divider to reach 400 kHz for MMC compatibility
+ mmc_compat_clk_div_g : integer := 0;
+ width_mmc_clk_div_g : integer := 0;
+ -- active level of reset_i
+ reset_level_g : integer := 0
+ );
+
+ port (
+ -- System Interface -------------------------------------------------------
+ clk_i : in std_logic;
+ reset_i : in std_logic;
+ set_sel_i : in std_logic_vector(width_set_sel_g-1 downto 0);
+ -- Card Interface ---------------------------------------------------------
+ spi_clk_o : out std_logic;
+ spi_cs_n_o : out std_logic;
+ spi_data_in_i : in std_logic;
+ spi_data_out_o : out std_logic;
+ spi_en_outs_o : out std_logic;
+ -- FPGA Configuration Interface -------------------------------------------
+ start_i : in std_logic;
+ mode_i : in std_logic;
+ config_n_o : out std_logic;
+ detached_o : out std_logic;
+ cfg_init_n_i : in std_logic;
+ cfg_done_i : in std_logic;
+ dat_done_i : in std_logic;
+ cfg_clk_o : out std_logic;
+ cfg_dat_o : out std_logic
+ );
+
+end spi_boot;
+
+
+library ieee;
+use ieee.numeric_std.all;
+use work.spi_boot_pack.all;
+
+architecture rtl of spi_boot is
+
+ component spi_counter
+ generic (
+ cnt_width_g : integer := 4;
+ cnt_max_g : integer := 15
+ );
+ port (
+ clk_i : in std_logic;
+ reset_i : in boolean;
+ cnt_en_i : in boolean;
+ cnt_o : out std_logic_vector(cnt_width_g-1 downto 0);
+ cnt_ovfl_o : out boolean
+ );
+ end component;
+
+
+ -----------------------------------------------------------------------------
+ -- States of the controller FSM
+ --
+ type ctrl_states_t is (POWER_UP1, POWER_UP2,
+ CMD0,
+ CMD1,
+ CMD55, ACMD41,
+ CMD16,
+ WAIT_START,
+ WAIT_INIT_LOW, WAIT_INIT_HIGH,
+ CMD18, CMD18_DATA,
+ CMD12,
+ INC_IMG_CNT);
+ --
+ signal ctrl_fsm_q,
+ ctrl_fsm_s : ctrl_states_t;
+ --
+ -----------------------------------------------------------------------------
+
+ -----------------------------------------------------------------------------
+ -- States of the command FSM
+ --
+ type cmd_states_t is (CMD, START, R1, PAUSE);
+ --
+ signal cmd_fsm_q,
+ cmd_fsm_s : cmd_states_t;
+ --
+ -----------------------------------------------------------------------------
+
+ subtype op_r is integer range 5 downto 0;
+ type res_bc_t is (NONE, RES_MAX, RES_47, RES_15, RES_7);
+ signal bit_cnt_q : unsigned(width_bit_cnt_g-1 downto 0);
+ signal res_bc_s : res_bc_t;
+ signal upper_bitcnt_zero_s : boolean;
+
+ signal cfg_dat_q : std_logic;
+
+ signal spi_clk_q : std_logic;
+ signal spi_clk_rising_q : boolean;
+ signal spi_clk_falling_q : boolean;
+ signal spi_dat_q,
+ spi_dat_s : std_logic;
+ signal spi_cs_n_q,
+ spi_cs_n_s : std_logic;
+
+ signal cfg_clk_q : std_logic;
+
+ signal start_q : std_logic;
+
+ signal img_cnt_s : std_logic_vector(width_img_cnt_g downto 0);
+ signal cnt_en_img_s : boolean;
+ signal mmc_cnt_ovfl_s : boolean;
+ signal mmc_compat_s : boolean;
+
+ signal cmd_finished_s : boolean;
+
+ signal r1_result_q : std_logic;
+ signal done_q,
+ send_cmd12_q : boolean;
+
+ signal en_outs_s,
+ en_outs_q : boolean;
+
+ signal reset_s : boolean;
+
+ signal true_s : boolean;
+
+begin
+
+ true_s <= true;
+
+ reset_s <= true
+ when (reset_level_g = 1 and reset_i = '1') or
+ (reset_level_g = 0 and reset_i = '0') else
+ false;
+
+ -----------------------------------------------------------------------------
+ -- Process seq
+ --
+ -- Purpose:
+ -- Implements several sequential elements.
+ --
+ seq: process (clk_i, reset_s)
+
+ variable bit_cnt_v : unsigned(1 downto 0);
+
+ begin
+ if reset_s then
+ -- reset bit counter to 63 for power up
+ bit_cnt_q <= (others => '0');
+ bit_cnt_q(op_r) <= "111111";
+ spi_dat_q <= '1';
+ spi_cs_n_q <= '1';
+ cfg_dat_q <= '1';
+ start_q <= '0';
+ done_q <= false;
+ send_cmd12_q <= false;
+ ctrl_fsm_q <= POWER_UP1;
+ cmd_fsm_q <= CMD;
+ r1_result_q <= '0';
+ en_outs_q <= false;
+
+ elsif clk_i'event and clk_i = '1' then
+ -- bit counter control
+ if spi_clk_rising_q then
+ case res_bc_s is
+ when NONE =>
+ bit_cnt_q <= bit_cnt_q - 1;
+ when RES_MAX =>
+ bit_cnt_q <= (others => '1');
+ when RES_47 =>
+ bit_cnt_q <= (others => '0');
+ bit_cnt_q(op_r) <= "101111";
+ when RES_15 =>
+ bit_cnt_q <= (others => '0');
+ bit_cnt_q(op_r) <= "001111";
+ when RES_7 =>
+ bit_cnt_q <= (others => '0');
+ bit_cnt_q(op_r) <= "000111";
+ when others =>
+ bit_cnt_q <= (others => '0');
+ end case;
+ end if;
+
+ -- Card data output register
+ -- spi_clk_falling_q acts as enable during MMC clock compatibility mode.
+ -- As soon as this mode is left, the register must start latching.
+ -- There is no explicit relation to spi_clk_q anymore in normal mode.
+ -- Instead, spi_dat_s is operated by bit_cnt_q above which changes its
+ -- value after the rising edge of spi_clk_q.
+ -- -> spi_dat_q changes upon falling edge of spi_clk_q
+ if spi_clk_falling_q or not mmc_compat_s then
+ spi_dat_q <= spi_dat_s;
+ end if;
+
+ -- config data output register
+ -- a new value is loaded when config clock is high,
+ -- i.e. input data is sampled with rising spi_clk
+ -- while output value changes on falling edge of cfg_clk
+ if cfg_clk_q = '1' and spi_clk_rising_q then
+ cfg_dat_q <= spi_data_in_i;
+ end if;
+
+ -- Controller FSM state
+ ctrl_fsm_q <= ctrl_fsm_s;
+
+ -- Command FSM state
+ cmd_fsm_q <= cmd_fsm_s;
+
+ -- CS signal for SPI card
+ if spi_clk_q = '1' then
+ spi_cs_n_q <= spi_cs_n_s;
+ end if;
+
+ -- Extract flags from R1 response
+ if cmd_fsm_q = R1 then
+ bit_cnt_v := bit_cnt_q(1 downto 0);
+ case bit_cnt_v(1 downto 0) is
+ when "10" =>
+ -- always save "Illegal Command" flag
+ r1_result_q <= to_X01(spi_data_in_i);
+ when "00" =>
+ -- overwrite with "Idle State" flag when not in CMD55
+ if ctrl_fsm_q /= CMD55 then
+ r1_result_q <= to_X01(spi_data_in_i);
+ end if;
+ when others =>
+ null;
+ end case;
+ end if;
+
+ -- Start trigger register for rising edge detection
+ -- the reset value is '0' thus a rising edge will always be detected
+ -- after reset even though start_i is tied to '1'
+ if start_i = '0' then
+ start_q <= '0';
+ elsif ctrl_fsm_q = WAIT_START and cmd_finished_s then
+ start_q <= start_i;
+ end if;
+
+ -- Marker for cfg_done and dat_done
+ if ctrl_fsm_q = CMD18_DATA then
+ if cfg_done_i = '1' and dat_done_i = '1' then
+ done_q <= true;
+ end if;
+
+ if done_q and
+ (not upper_bitcnt_zero_s or cmd_fsm_q = START) then
+ -- activate sending of CMD12 when it is safe:
+ -- * upper bits of bit counter are not zero
+ -- -> transmission of CMD12 is not running
+ -- * cmd FSM is in START state
+ -- -> also no transmission running
+ send_cmd12_q <= true;
+ end if;
+ elsif ctrl_fsm_q = WAIT_START then
+ -- reset done_q when WAIT_START has been reached
+ -- this is necessary to let the stop transmission process come to
+ -- an end without interruption or generation of unwanted cfg_clk_q
+ done_q <= false;
+ send_cmd12_q <= false;
+ end if;
+
+ -- output enable
+ if spi_clk_rising_q then
+ en_outs_q <= en_outs_s;
+ end if;
+
+ end if;
+
+ end process seq;
+ --
+ -----------------------------------------------------------------------------
+
+
+ -----------------------------------------------------------------------------
+ -- Process upper_bits
+ --
+ -- Purpose:
+ -- Detects that the upper bits of the bit counter are zero.
+ -- Upper bits = n downto 6, i.e. the optional part that is not required for
+ -- commands but for extension of data blocks.
+ --
+ upper_bits: process (bit_cnt_q)
+ variable zero_v : boolean;
+ begin
+
+ zero_v := true;
+ for i in bit_cnt_q'high downto 6 loop
+ if bit_cnt_q(i) = '1' then
+ zero_v := false;
+ end if;
+ end loop;
+
+ upper_bitcnt_zero_s <= zero_v;
+
+ end process upper_bits;
+ --
+ -----------------------------------------------------------------------------
+
+
+ -----------------------------------------------------------------------------
+ -- Process clk_gen
+ --
+ -- Purpose:
+ -- Generates clocks for card and FPGA configuration.
+ -- The card clock is free running with a divide by two of clk_i.
+ -- The clock for FPGA config has an enable and is stopped on high level.
+ -- There is a phase shift of half a period between spi_clk and cfg_clk.
+ --
+ clk_gen: process (clk_i, reset_s)
+ begin
+ if reset_s then
+ spi_clk_q <= '0';
+ cfg_clk_q <= '1';
+
+ elsif clk_i'event and clk_i = '1' then
+
+ -- spi_clk_q rises according to the flag
+ -- it falls with overflow indication
+ -- the resulting duty cycle is not exactly 50:50,
+ -- high time is a bit longer
+ if mmc_compat_s then
+ -- MMC clock compatibility mode:
+ -- spi_clk_q rises when flagged by spi_clk_rising_q
+ if spi_clk_rising_q then
+ spi_clk_q <= '1';
+ elsif mmc_cnt_ovfl_s then
+ -- upon counter overflow spi_clk_q falls in case it does not rise
+ spi_clk_q <= '0';
+ end if;
+ else
+ -- normal mode
+ -- spi_clk_q follows spi_clk_rising_q
+ if spi_clk_rising_q then
+ spi_clk_q <= '1';
+ else
+ spi_clk_q <= '0';
+ end if;
+ end if;
+
+ -- clock for FPGA config must be enabled and follows spi_clk
+ if ctrl_fsm_q = CMD18_DATA and cmd_fsm_q = CMD and
+ not done_q then
+ cfg_clk_q <= spi_clk_q;
+ else
+ cfg_clk_q <= '1';
+ end if;
+
+ end if;
+
+ end process clk_gen;
+ --
+ -----------------------------------------------------------------------------
+
+
+ -----------------------------------------------------------------------------
+ -- Indication flags for rising and falling spi_clk_q.
+ -- Essential for MMC clock compatibility mode.
+ -----------------------------------------------------------------------------
+ mmc_comap: if mmc_compat_clk_div_g > 0 generate
+ mmc_compat_sig: process (clk_i, reset_s)
+ begin
+ if reset_s then
+ spi_clk_rising_q <= false;
+ spi_clk_falling_q <= false;
+
+ elsif clk_i'event and clk_i = '1' then
+ if mmc_compat_s then
+ -- MMC clock compatibility mode:
+ -- spi_clk_rising_q is an impulse right before rising edge of spi_clk_q
+ -- spi_clk_falling_q is an impulse right before falling edge of spi_clk_q
+ if mmc_cnt_ovfl_s then
+ spi_clk_rising_q <= spi_clk_q = '0';
+ spi_clk_falling_q <= spi_clk_q = '1';
+ else
+ spi_clk_rising_q <= false;
+ spi_clk_falling_q <= false;
+ end if;
+ else
+ -- normal mode
+ spi_clk_rising_q <= not spi_clk_rising_q;
+ spi_clk_falling_q <= true;
+ end if;
+
+ end if;
+ end process mmc_compat_sig;
+ end generate;
+
+ no_mmc_compat: if mmc_compat_clk_div_g = 0 generate
+ -- SPI clock rising whenever spi_clk_q is '0'
+ spi_clk_rising_q <= spi_clk_q = '0';
+ -- SPI clock falling whenever spi_clk_q is '1'
+ spi_clk_falling_q <= spi_clk_q = '1';
+ end generate;
+
+
+ -----------------------------------------------------------------------------
+ -- Process ctrl_fsm
+ --
+ -- Purpose:
+ -- Implements the controller FSM.
+ --
+ ctrl_fsm: process (ctrl_fsm_q,
+ cmd_finished_s, r1_result_q,
+ start_i, start_q, mode_i,
+ cfg_init_n_i)
+
+ variable mmc_compat_v : boolean;
+
+ begin
+ -- default assignments
+ ctrl_fsm_s <= POWER_UP1;
+ config_n_o <= '1';
+ cnt_en_img_s <= false;
+ spi_cs_n_s <= '0';
+ mmc_compat_v := false;
+ en_outs_s <= true;
+
+ case ctrl_fsm_q is
+ -- Let card finish power up, step 1 -------------------------------------
+ when POWER_UP1 =>
+ mmc_compat_v := true;
+ spi_cs_n_s <= '1';
+ if cmd_finished_s then
+ ctrl_fsm_s <= POWER_UP2;
+ else
+ ctrl_fsm_s <= POWER_UP1;
+ end if;
+
+
+ -- Let card finish power up, step 2 -------------------------------------
+ when POWER_UP2 =>
+ mmc_compat_v := true;
+ if cmd_finished_s then
+ ctrl_fsm_s <= CMD0;
+ else
+ spi_cs_n_s <= '1';
+ ctrl_fsm_s <= POWER_UP2;
+ end if;
+
+
+ -- Issue CMD0: GO_IDLE_STATE --------------------------------------------
+ when CMD0 =>
+ mmc_compat_v := true;
+ if cmd_finished_s then
+ if sd_init_g = 1 then
+ ctrl_fsm_s <= CMD55;
+ else
+ ctrl_fsm_s <= CMD1;
+ end if;
+ else
+ ctrl_fsm_s <= CMD0;
+ end if;
+
+
+ -- Issue CMD55: APP_CMD -------------------------------------------------
+ when CMD55 =>
+ if sd_init_g = 1 then
+
+ mmc_compat_v := true;
+ if cmd_finished_s then
+ if r1_result_q = '0' then
+ -- command accepted, it's an SD card
+ ctrl_fsm_s <= ACMD41;
+ else
+ -- command rejected, it's an MMC card
+ ctrl_fsm_s <= CMD1;
+ end if;
+ else
+ ctrl_fsm_s <= CMD55;
+ end if;
+
+ end if;
+
+
+ -- Issue ACMD41: SEND_OP_COND -------------------------------------------
+ when ACMD41 =>
+ if sd_init_g = 1 then
+
+ mmc_compat_v := true;
+ if cmd_finished_s then
+ if r1_result_q = '0' then
+ ctrl_fsm_s <= CMD16;
+ else
+ ctrl_fsm_s <= CMD55;
+ end if;
+ else
+ ctrl_fsm_s <= ACMD41;
+ end if;
+
+ end if;
+
+
+ -- Issue CMD1: SEND_OP_COND ---------------------------------------------
+ when CMD1 =>
+ mmc_compat_v := true;
+ if cmd_finished_s then
+ if r1_result_q = '0' then
+ ctrl_fsm_s <= CMD16;
+ else
+ ctrl_fsm_s <= CMD1;
+ end if;
+ else
+ ctrl_fsm_s <= CMD1;
+ end if;
+
+
+ -- Issue CMD16: SET_BLOCKLEN --------------------------------------------
+ when CMD16 =>
+ if cmd_finished_s then
+ ctrl_fsm_s <= WAIT_START;
+ else
+ ctrl_fsm_s <= CMD16;
+ end if;
+
+
+ -- Wait for configuration start request ---------------------------------
+ when WAIT_START =>
+ spi_cs_n_s <= '1';
+
+ -- detect rising edge of start_i
+ if start_i = '1' and start_q = '0' then
+ -- decide which mode is requested
+ if cmd_finished_s then
+ if mode_i = '0' then
+ ctrl_fsm_s <= CMD18;
+ else
+ ctrl_fsm_s <= WAIT_INIT_LOW;
+ end if;
+ else
+ en_outs_s <= false;
+ ctrl_fsm_s <= WAIT_START;
+ end if;
+ else
+ en_outs_s <= false;
+ ctrl_fsm_s <= WAIT_START;
+ end if;
+
+
+ -- Wait for INIT to become low ------------------------------------------
+ when WAIT_INIT_LOW =>
+ spi_cs_n_s <= '1';
+ -- activate FPGA configuration
+ config_n_o <= '0';
+
+ if cfg_init_n_i = '0' then
+ ctrl_fsm_s <= WAIT_INIT_HIGH;
+ else
+ ctrl_fsm_s <= WAIT_INIT_LOW;
+ end if;
+
+
+ -- Wait for INIT to become high -----------------------------------------
+ when WAIT_INIT_HIGH =>
+ spi_cs_n_s <= '1';
+
+ if cfg_init_n_i = '1' and cmd_finished_s then
+ ctrl_fsm_s <= CMD18;
+ else
+ ctrl_fsm_s <= WAIT_INIT_HIGH;
+ end if;
+
+
+ -- Issue CMD18: READ_MULTIPLE_BLOCKS ------------------------------------
+ when CMD18 =>
+ if cmd_finished_s then
+ ctrl_fsm_s <= CMD18_DATA;
+ else
+ ctrl_fsm_s <= CMD18;
+ end if;
+ --
+ -- receive a data block
+ when CMD18_DATA =>
+ if cmd_finished_s then
+ ctrl_fsm_s <= CMD12;
+ else
+ ctrl_fsm_s <= CMD18_DATA;
+ end if;
+
+
+ -- Issued CMD12: STOP_TRANSMISSION --------------------------------------
+ when CMD12 =>
+ if cmd_finished_s then
+ ctrl_fsm_s <= INC_IMG_CNT;
+ else
+ ctrl_fsm_s <= CMD12;
+ end if;
+
+
+ -- Increment Image Counter ----------------------------------------------
+ when INC_IMG_CNT =>
+ spi_cs_n_s <= '1';
+ ctrl_fsm_s <= WAIT_START;
+ cnt_en_img_s <= true;
+
+
+
+ when others =>
+ null;
+
+ end case;
+
+ -- mmc_compat_s is suppressed if MMC clock compatibility is not required
+ if mmc_compat_clk_div_g > 0 then
+ mmc_compat_s <= mmc_compat_v;
+ else
+ mmc_compat_s <= false;
+ end if;
+
+ end process ctrl_fsm;
+ --
+ -----------------------------------------------------------------------------
+
+
+ -----------------------------------------------------------------------------
+ -- Process cmd_fsm
+ --
+ -- Purpose:
+ -- Implements the command FSM.
+ --
+ cmd_fsm: process (spi_clk_rising_q,
+ spi_data_in_i,
+ bit_cnt_q,
+ ctrl_fsm_q,
+ cmd_fsm_q,
+ send_cmd12_q)
+
+ variable cnt_zero_v : boolean;
+ variable spi_data_low_v : boolean;
+ variable no_startbit_v : boolean;
+
+ begin
+ -- default assignments
+ cmd_finished_s <= false;
+ cmd_fsm_s <= CMD;
+ res_bc_s <= NONE;
+
+ cnt_zero_v := spi_clk_rising_q and bit_cnt_q = 0;
+ spi_data_low_v := spi_clk_rising_q and spi_data_in_i = '0';
+
+ -- these are no real commands thus there will be no startbit
+ case ctrl_fsm_q is
+ when POWER_UP1 | POWER_UP2 |
+ WAIT_START | WAIT_INIT_HIGH | WAIT_INIT_LOW =>
+ no_startbit_v := true;
+ when others =>
+ no_startbit_v := false;
+ end case;
+
+
+ case cmd_fsm_q is
+ -- Send the command -----------------------------------------------------
+ when CMD =>
+ if cnt_zero_v then
+ if ctrl_fsm_q /= CMD18_DATA then
+ -- normal commands including CMD12 require startbit of R1 response
+ cmd_fsm_s <= START;
+ else
+ if not send_cmd12_q then
+ -- CMD18_DATA needs to read CRC
+ cmd_fsm_s <= R1;
+ res_bc_s <= RES_15;
+ else
+ -- CMD18_DATA finished, scan for startbit of response
+ cmd_finished_s <= true;
+ cmd_fsm_s <= START;
+ end if;
+ end if;
+ else
+ cmd_fsm_s <= CMD;
+ end if;
+
+ -- Wait for startbit of response ----------------------------------------
+ when START =>
+ -- startbit detection or skip of this check
+ if no_startbit_v and spi_clk_rising_q then
+ cmd_fsm_s <= R1;
+ res_bc_s <= RES_7;
+ elsif spi_data_low_v then
+ if ctrl_fsm_q /= CMD18_DATA then
+ cmd_fsm_s <= R1;
+ else
+ -- CMD18_DATA startbit detected, read payload
+ cmd_fsm_s <= CMD;
+ res_bc_s <= RES_MAX;
+ end if;
+ else
+ cmd_fsm_s <= START;
+ res_bc_s <= RES_7;
+ end if;
+
+ -- Read R1 response -----------------------------------------------------
+ when R1 =>
+ if cnt_zero_v then
+ res_bc_s <= RES_7;
+
+ if not (ctrl_fsm_q = CMD18 or ctrl_fsm_q = CMD18_DATA) then
+ cmd_fsm_s <= PAUSE;
+ else
+ -- CMD18 needs another startbit detection for the data token.
+ -- CMD18_DATA needs a startbit after having received the CRC, either
+ -- * next data token
+ -- * R1 response of CMD12
+ cmd_fsm_s <= START;
+
+ if ctrl_fsm_q = CMD18 then
+ -- CMD18 response received -> advance to CMD18_DATA
+ cmd_finished_s <= true;
+ end if;
+ end if;
+ else
+ cmd_fsm_s <= R1;
+ end if;
+
+ -- PAUSE state -> required for Nrc, card response to host command -------
+ when PAUSE =>
+ if cnt_zero_v then
+ cmd_fsm_s <= CMD;
+ res_bc_s <= RES_47;
+ cmd_finished_s <= true;
+ else
+ cmd_fsm_s <= PAUSE;
+ end if;
+
+ when others =>
+ null;
+
+ end case;
+
+ end process cmd_fsm;
+ --
+ -----------------------------------------------------------------------------
+
+
+ -----------------------------------------------------------------------------
+ -- Process transmit
+ --
+ -- Purpose:
+ -- Generates the serial data output values based on the current FSM state
+ --
+ -- The local variable cmd_v is 64 bits wide in contrast to an SPI command
+ -- with 48 bits. There are two reasons for this:
+ -- * During "overlaid" sending of CMD12 in FSM state CMD18_DATA, the bit
+ -- counter will start from 3F on its lowest 6 bits. Therefore, it is
+ -- necessary to provide all 64 positions in cmd_v.
+ -- * Reduces logic.
+ --
+ transmit: process (ctrl_fsm_q,
+ cmd_fsm_q,
+ bit_cnt_q,
+ img_cnt_s,
+ send_cmd12_q,
+ set_sel_i,
+ upper_bitcnt_zero_s)
+
+ subtype cmd_r is natural range 47 downto 0;
+ subtype cmd_t is std_logic_vector(cmd_r);
+ subtype ext_cmd_t is std_logic_vector(63 downto 0);
+ -- STCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcccccccS
+ constant cmd0_c : cmd_t := "010000000000000000000000000000000000000010010101";
+ constant cmd1_c : cmd_t := "0100000100000000000000000000000000000000-------1";
+ constant cmd12_c : cmd_t := "0100110000000000000000000000000000000000-------1";
+ constant cmd16_c : cmd_t := "0101000000000000000000000000000000000000-------1";
+ constant cmd18_c : cmd_t := "0101001000000000000000000000000000000000-------1";
+ constant cmd55_c : cmd_t := "0111011100000000000000000000000000000000-------1";
+ constant acmd41_c : cmd_t := "0110100100000000000000000000000000000000-------1";
+
+ variable cmd_v : ext_cmd_t;
+ variable tx_v : boolean;
+
+ begin
+ -- default assignments
+ spi_dat_s <= '1';
+ cmd_v := (others => '1');
+ tx_v := false;
+
+ if cmd_fsm_q = CMD then
+ case ctrl_fsm_q is
+ when CMD0 =>
+ cmd_v(cmd_r) := cmd0_c;
+ tx_v := true;
+ when CMD1 =>
+ cmd_v(cmd_r) := cmd1_c;
+ tx_v := true;
+ when CMD16 =>
+ cmd_v(cmd_r) := cmd16_c;
+ cmd_v(8 + width_bit_cnt_g-3) := '1';
+ tx_v := true;
+ when CMD18 =>
+ cmd_v(cmd_r) := cmd18_c;
+ -- insert image counter
+ cmd_v(8 + num_bits_per_img_g + width_img_cnt_g
+ downto 8 + num_bits_per_img_g) := img_cnt_s;
+ -- insert set selection
+ cmd_v(8 + num_bits_per_img_g + width_img_cnt_g + width_set_sel_g-1
+ downto 8 + num_bits_per_img_g + width_img_cnt_g) := set_sel_i;
+ tx_v := true;
+ when CMD18_DATA =>
+ cmd_v(cmd_r) := cmd12_c;
+
+ if send_cmd12_q and upper_bitcnt_zero_s then
+ tx_v := true;
+ end if;
+ when CMD55 =>
+ cmd_v(cmd_r) := cmd55_c;
+ tx_v := true;
+ when ACMD41 =>
+ cmd_v(cmd_r) := acmd41_c;
+ tx_v := true;
+
+ when others =>
+ null;
+ end case;
+ end if;
+
+ if tx_v then
+ spi_dat_s <= cmd_v(to_integer(bit_cnt_q(5 downto 0)));
+ end if;
+
+ end process transmit;
+ --
+ -----------------------------------------------------------------------------
+
+
+ -----------------------------------------------------------------------------
+ -- Optional Image Counter
+ -----------------------------------------------------------------------------
+ img_cnt: if width_img_cnt_g > 0 generate
+ img_cnt_b : spi_counter
+ generic map (
+ cnt_width_g => width_img_cnt_g,
+ cnt_max_g => 2**width_img_cnt_g - 1
+ )
+ port map (
+ clk_i => clk_i,
+ reset_i => reset_s,
+ cnt_en_i => cnt_en_img_s,
+ cnt_o => img_cnt_s(width_img_cnt_g-1 downto 0),
+ cnt_ovfl_o => open
+ );
+ img_cnt_s(width_img_cnt_g) <= '0';
+ end generate;
+
+ no_img_cnt: if width_img_cnt_g = 0 generate
+ img_cnt_s <= (others => '0');
+ end generate;
+
+
+ -----------------------------------------------------------------------------
+ -- Optional MMC compatibility counter
+ -----------------------------------------------------------------------------
+ mmc_cnt: if mmc_compat_clk_div_g > 0 generate
+ mmc_cnt_b : spi_counter
+ generic map (
+ cnt_width_g => width_mmc_clk_div_g,
+ cnt_max_g => mmc_compat_clk_div_g
+ )
+ port map (
+ clk_i => clk_i,
+ reset_i => reset_s,
+ cnt_en_i => true_s,
+ cnt_o => open,
+ cnt_ovfl_o => mmc_cnt_ovfl_s
+ );
+ end generate;
+
+ no_mmc_cnt: if mmc_compat_clk_div_g = 0 generate
+ mmc_cnt_ovfl_s <= true;
+ end generate;
+
+
+ -----------------------------------------------------------------------------
+ -- Output Mapping
+ -----------------------------------------------------------------------------
+ spi_clk_o <= spi_clk_q;
+ spi_cs_n_o <= spi_cs_n_q;
+ spi_data_out_o <= spi_dat_q;
+ spi_en_outs_o <= '1'
+ when en_outs_q else
+ '0';
+ cfg_clk_o <= cfg_clk_q;
+ cfg_dat_o <= cfg_dat_q;
+ detached_o <= '0'
+ when en_outs_q else
+ '1';
+
+end rtl;
+
+
+-------------------------------------------------------------------------------
+-- File History:
+--
+-- $Log: spi_boot.vhd,v $
+-- Revision 1.9 2007/02/25 18:24:12 arniml
+-- fix type handling of resets
+--
+-- Revision 1.8 2006/09/11 23:03:36 arniml
+-- disable outputs with reset
+--
+-- Revision 1.7 2005/04/07 20:44:23 arniml
+-- add new port detached_o
+--
+-- Revision 1.6 2005/03/09 19:48:34 arniml
+-- invert level of set_sel input
+--
+-- Revision 1.5 2005/03/08 22:07:12 arniml
+-- added set selection
+--
+-- Revision 1.4 2005/02/18 06:42:08 arniml
+-- clarify wording for images
+--
+-- Revision 1.3 2005/02/16 18:59:10 arniml
+-- include output enable control for SPI outputs
+--
+-- Revision 1.2 2005/02/13 17:25:51 arniml
+-- major update to fix several problems
+-- configuration/data download of multiple sets works now
+--
+-- Revision 1.1 2005/02/08 20:41:33 arniml
+-- initial check-in
+--
+-------------------------------------------------------------------------------
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot_pack-p.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot_pack-p.vhd
new file mode 100644
index 000000000..ac8b544f9
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_boot_pack-p.vhd
@@ -0,0 +1,54 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+--
+-- $Id: spi_boot_pack-p.vhd,v 1.1 2005/02/08 20:41:33 arniml Exp $
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+package spi_boot_pack is
+
+ function "=" (a : std_logic; b : integer) return boolean;
+
+end spi_boot_pack;
+
+package body spi_boot_pack is
+
+ function "=" (a : std_logic; b : integer) return boolean is
+ variable result_v : boolean;
+ begin
+ result_v := false;
+
+ case a is
+ when '0' =>
+ if b = 0 then
+ result_v := true;
+ end if;
+
+ when '1' =>
+ if b = 1 then
+ result_v := true;
+ end if;
+
+ when others =>
+ null;
+
+ end case;
+
+ return result_v;
+ end;
+
+end spi_boot_pack;
+
+
+-------------------------------------------------------------------------------
+-- File History:
+--
+-- $Log: spi_boot_pack-p.vhd,v $
+-- Revision 1.1 2005/02/08 20:41:33 arniml
+-- initial check-in
+--
+-------------------------------------------------------------------------------
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_counter-c.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_counter-c.vhd
new file mode 100644
index 000000000..d81e20db6
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_counter-c.vhd
@@ -0,0 +1,14 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+--
+-- $Id: spi_counter-c.vhd,v 1.1 2005/02/08 20:41:33 arniml Exp $
+--
+-------------------------------------------------------------------------------
+
+configuration spi_counter_rtl_c0 of spi_counter is
+
+ for rtl
+ end for;
+
+end spi_counter_rtl_c0;
diff --git a/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_counter.vhd b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_counter.vhd
new file mode 100644
index 000000000..8ec7357ea
--- /dev/null
+++ b/fpga/usrp2/opencores/spi_boot/rtl/vhdl/spi_counter.vhd
@@ -0,0 +1,118 @@
+-------------------------------------------------------------------------------
+--
+-- SD/MMC Bootloader
+-- Generic counter module
+--
+-- $Id: spi_counter.vhd,v 1.2 2007/02/25 18:24:12 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 spi_counter is
+
+ generic (
+ cnt_width_g : integer := 4;
+ cnt_max_g : integer := 15
+ );
+
+ port (
+ clk_i : in std_logic;
+ reset_i : in boolean;
+ cnt_en_i : in boolean;
+ cnt_o : out std_logic_vector(cnt_width_g-1 downto 0);
+ cnt_ovfl_o : out boolean
+ );
+
+end spi_counter;
+
+
+library ieee;
+use ieee.numeric_std.all;
+use work.spi_boot_pack.all;
+
+architecture rtl of spi_counter is
+
+ signal cnt_q : unsigned(cnt_width_g-1 downto 0);
+ signal cnt_ovfl_s : boolean;
+
+begin
+
+ cnt: process (clk_i, reset_i)
+ begin
+ if reset_i then
+ cnt_q <= (others => '0');
+
+ elsif clk_i'event and clk_i = '1' then
+ if cnt_en_i then
+ if not cnt_ovfl_s then
+ cnt_q <= cnt_q + 1;
+ else
+ cnt_q <= (others => '0');
+ end if;
+ end if;
+ end if;
+ end process cnt;
+
+ cnt_ovfl_s <= cnt_q = cnt_max_g;
+
+
+ -----------------------------------------------------------------------------
+ -- Output Mapping
+ -----------------------------------------------------------------------------
+ cnt_ovfl_o <= cnt_ovfl_s;
+ cnt_o <= std_logic_vector(cnt_q);
+
+end rtl;
+
+
+-------------------------------------------------------------------------------
+-- File History:
+--
+-- $Log: spi_counter.vhd,v $
+-- Revision 1.2 2007/02/25 18:24:12 arniml
+-- fix type handling of resets
+--
+-- Revision 1.1 2005/02/08 20:41:33 arniml
+-- initial check-in
+--
+-------------------------------------------------------------------------------