--                                                               
-- config_top.vhd
--
-- This design uses the sconfig block and a couple Fusion NVM blocks
-- to demonstrate logic to configure an Xilinx FPGA from Fusion.
--        
--****************************************************************************
-- IMPORTANT-READ THESE TERMS CAREFULLY BEFORE UTILIZING THE INFORMATION
-- CONTAINED IN THIS APPLICATION NOTE. 
--
-- NO SUPPORT/NO WARRANTY. THE DESIGN FILES AND DOCUMENTATION ARE PROVIDED
-- WITHOUT SUPPORT OR WARRANTY OF ANY KIND. ACTEL IS NOT OBLIGATED TO 
-- PROVIDE UPDATES, BUG FIXES, OR TECHNICAL SUPPORT AND DISCLAIMS ALL 
-- WARRANTIES INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE, AND WARRANTIES OF NON-INFRINGEMENT OF THE
-- RIGHTS OF THIRD PARTIES (INCLUDING, WITHOUT LIMITATION, RIGHTS UNDER PATENT,
-- COPYRIGHT, TRADE SECRET, OR OTHER INTELLECTUAL PROPERTY RIGHTS).  RECIPIENT
-- ACCEPTS THE APPLICATION NOTE DESIGN FILES AND DOCUMENTATION IN "AS-IS"
-- CONDITION.
--*****************************************************************************

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity config_top is 
port(RST    : in    std_logic; -- Starter Kit is active high
     CSn    : in    std_logic;
     CLK    : in    std_logic;      
     DI     : in    std_logic;
     DO     : inout std_logic
);
end config_top;

architecture rtl of config_top is

component rc_osc is 
    port(CLKOUT : out std_logic) ;
end component;

component PLL_60_40_10 is 
    port(POWERDOWN, CLKA : in std_logic;  LOCK, GLA, GLB, GLC : 
        out std_logic;  OADIVRST : in std_logic) ;
end component;

component sconfig is 
port(rstn   : in    std_logic;
     fclk   : in    std_logic;

     CSn    : in    std_logic;
     CLK    : in    std_logic;      
     DI     : in    std_logic;
     DO     : inout std_logic;

     addr      : out   std_logic_vector(18 downto 0);
     din       : in    std_logic_vector( 7 downto 0);
     dout      : out   std_logic_vector( 7 downto 0);
     rden      : out   std_logic;
     nvm_busy  : in    std_logic;
     nvm_erase : out   std_logic;
     nvm_pgm   : out   std_logic;
     nvm_we    : out   std_logic
);
end component;

component NVM_2_blocks is 
port(rstn		: in    std_logic; -- 
     clk60M		: in    std_logic;
     nvm_addr   : in    std_logic_vector(18 downto 0);      
     nvm_read   : in    std_logic;
     nvm_dout	: out	std_logic_vector(7 downto 0);
	 nvm_din	: in	std_logic_vector(31 downto 0);
	 nvm_busy	: out	std_logic;
	 nvm_erase  : in	std_logic;
	 nvm_pgm	: in	std_logic;
	 nvm_we		: in	std_logic
);
end component;

signal rstn      : std_logic;
signal clk100M   : std_logic;
signal clk60M    : std_logic;
signal clk40M    : std_logic;
signal clk10M    : std_logic;

signal busy1     : std_logic;
signal busy2     : std_logic;
signal nvm_busy  : std_logic;
signal nvm_erase : std_logic;
signal nvm_pgm   : std_logic;
signal nvm_we    : std_logic;

signal nvm_addr  : std_logic_vector(18 downto 0);
signal nvm_din   : std_logic_vector(31 downto 0);
signal nvm_dout  : std_logic_vector( 7 downto 0);

signal nvm_read  : std_logic;

begin

rstn <= NOT(rst);
nvm_din(31 downto 8) <= (OTHERS => '0');

C1: rc_osc  
port map(CLKOUT => clk100M);

C2: PLL_60_40_10  
port map(POWERDOWN => '1',
         OADIVRST  => rstn,
         CLKA      => clk100M,
         GLA       => clk60M,
         GLB       => clk40M,
         GLC       => clk10M,
         LOCK      => open
);

U1: sconfig
port map (rstn   => rstn,
          fclk   => CLK60M,

          CSn    => CSn,
          CLK    => CLK,    
          DI     => DI,
          DO     => DO,

          addr   => nvm_addr,
          rden   => nvm_read,
          din    => nvm_dout,
          dout   => nvm_din(7 downto 0),

          nvm_busy  => nvm_busy,
          nvm_erase => nvm_erase,
          nvm_pgm   => nvm_pgm,
          nvm_we    => nvm_we
);

U2: NVM_2_blocks
port map (
			rstn		=> rstn,
			clk60M		=> CLK60M,
			nvm_addr	=> nvm_addr,
			nvm_read	=> nvm_read,
		    nvm_dout	=> nvm_dout,
		    nvm_din		=> nvm_din,
			nvm_busy	=> nvm_busy,
			nvm_erase   => nvm_erase,
			nvm_pgm		=> nvm_pgm,
			nvm_we		=> nvm_we
);


end rtl;