----------------------------------------------------------------------------------
--
-- Copyright CERN 2011.
-- 
-- This documentation describes Open Hardware and is licensed under the
-- CERN OHL v. 1.1.
--
-- You may redistribute and modify this documentation under the terms of the CERN
-- OHL v.1.1. (http://ohwr.org/cernohl).
--
-- This documentation is distributed WITHOUT
-- ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY
-- QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN OHL v.1.1 for
-- applicable conditions.
--
----------------------------------------------------------------------------------
--
-- Company:        CERN, BE-CO-HT 
-- Engineer:       Carlos Gil Soriano
-- 
-- Create Date:    01:22:27 06/11/2012 
-- Design Name:    m25p32 top level
-- Module Name:    m25p32_top - Behavioral 
-- Project Name:   Level Conversion Circuits
-- Target Devices: Spartan 6
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use work.m25p32_pkg.ALL;
use work.spi_master_pkg.ALL;


entity m25p32_top is
   generic(
           g_WB_ADDR_LENGTH : NATURAL := c_WORDS_PER_PAGE_BITS + 1);
   port ( 
           wb_rst_i       : in  STD_LOGIC;
           wb_clk         : in  STD_LOGIC;

           wb_we_i        : in  STD_LOGIC;
           wb_stb_i       : in  STD_LOGIC;
           wb_cyc_i       : in  STD_LOGIC;
           wb_sel_i       : in  STD_LOGIC_VECTOR (3  downto 0);
           wb_data_i      : in  STD_LOGIC_VECTOR (31 downto 0); 
           wb_data_o      : out STD_LOGIC_VECTOR (31 downto 0); 
           wb_addr_i      : in  STD_LOGIC_VECTOR (g_WB_ADDR_LENGTH - 1 downto 0); 
           wb_ack_o       : out STD_LOGIC; 
           wb_rty_o       : out STD_LOGIC; 
           wb_err_o       : out STD_LOGIC;

           miso_word_rcv  : out STD_LOGIC;
           op_finished_o  : out STD_LOGIC;

           prom_mosi_o    : out STD_LOGIC;
           prom_cclk_o    : out STD_LOGIC;
           prom_cs0_b_n_o : out STD_LOGIC;
           prom_din_i     : in  STD_LOGIC
        );
end m25p32_top;

architecture Behavioral of m25p32_top is

   signal  s_wr_data   : STD_LOGIC_VECTOR (c_DATA_LENGTH*8 - 1 downto 0);
   signal  s_rd_data   : STD_LOGIC_VECTOR (c_READ_LENGTH*8 - 1 downto 0);
   signal  s_SR_m25p32 : STD_LOGIC_VECTOR (r_SR_m25p32'a_length - 1 downto 0);

   signal  s_OP        : STD_LOGIC_VECTOR (r_OP'a_length  - 1 downto 0);
   signal  s_FMI       : STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0);

   signal s_rd_SPI3    : STD_LOGIC;

   component m25p32_core is
      generic(
           g_INST_LENGTH     : NATURAL := c_INST_LENGTH;
           g_ADDR_LENGTH     : NATURAL := c_ADDR_LENGTH;
           g_PAGE_SIZE       : NATURAL := c_PAGE_SIZE;
           g_CLK_I_PERIOD    : NATURAL := c_CLK_I_PERIOD);
      port (
              wb_rst_i    : in  STD_LOGIC;
              wb_clk      : in  STD_LOGIC;

              mosi_o      : out STD_LOGIC;
              miso_i      : in  STD_LOGIC;
              sclk_o      : out STD_LOGIC;
              ss_n_o      : out STD_LOGIC;

              wr_data_i   : in  STD_LOGIC_VECTOR (g_PAGE_SIZE*8   - 1  downto 0);
              rd_data_o   : out STD_LOGIC_VECTOR (r_SPI3'a_length - 1  downto 0);
              SR_m25p32_i : in  STD_LOGIC_VECTOR (r_SR_m25p32'a_length - 1 downto 0);

              rd_SPI3_o   : out STD_LOGIC;

              OP_o        : out STD_LOGIC_VECTOR (r_OP'a_length  - 1 downto 0);
              FMI_i       : in  STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0)
           );
   end component;

   component m25p32_regs is
      generic(
             g_INST_LENGTH    : NATURAL := c_INST_LENGTH; 
             g_ADDR_LENGTH    : NATURAL := c_ADDR_LENGTH; 
             g_DATA_LENGTH    : NATURAL := c_DATA_LENGTH;
             g_READ_LENGTH    : NATURAL := c_READ_LENGTH;
             g_WB_ADDR_LENGTH : NATURAL := c_WORDS_PER_PAGE_BITS + 1);
      port (
              wb_rst_i      : in  STD_LOGIC;
              wb_clk        : in  STD_LOGIC;

              wb_we_i       : in  STD_LOGIC;
              wb_stb_i      : in  STD_LOGIC;
              wb_cyc_i      : in  STD_LOGIC;
              wb_sel_i      : in  STD_LOGIC_VECTOR (3  downto 0);
              wb_data_i     : in  STD_LOGIC_VECTOR (31 downto 0);
              wb_data_o     : out STD_LOGIC_VECTOR (31 downto 0);
              wb_addr_i     : in  STD_LOGIC_VECTOR (g_WB_ADDR_LENGTH - 1 downto 0);
              wb_ack_o      : out STD_LOGIC;
              wb_rty_o      : out STD_LOGIC;
              wb_err_o      : out STD_LOGIC;

              rd_SPI3_i     : in  STD_LOGIC;

              wr_data_o     : out STD_LOGIC_VECTOR (g_DATA_LENGTH*8 - 1 downto 0);
              rd_data_i     : in  STD_LOGIC_VECTOR (g_READ_LENGTH*8 - 1 downto 0);

              SR_m25p32_o   : out STD_LOGIC_VECTOR (r_SR_m25p32'a_length - 1 downto 0);

              OP_i          : in  STD_LOGIC_VECTOR (r_OP'a_length  - 1 downto 0);
              FMI_o         : out STD_LOGIC_VECTOR (r_FMI'a_length - 1 downto 0)
           );
   end component;

begin

   op_finished_o <= f_OP(s_OP).OPF;

   inst_m25p32_core: m25p32_core
   port map (
               wb_rst_i      => wb_rst_i, 
               wb_clk        => wb_clk, 

               mosi_o        => prom_mosi_o, 
               miso_i        => prom_din_i, 
               sclk_o        => prom_cclk_o, 
               ss_n_o        => prom_cs0_b_n_o,

               wr_data_i     => s_wr_data, 
               rd_data_o     => s_rd_data, 
               SR_m25p32_i   => s_SR_m25p32, 

               rd_SPI3_o     => s_rd_SPI3,

               OP_o          => s_OP,
               FMI_i         => s_FMI
            );

   inst_m25p32_regs:   m25p32_regs
   port map (
               wb_rst_i      => wb_rst_i, 
               wb_clk        => wb_clk, 

               wb_we_i       => wb_we_i, 
               wb_stb_i      => wb_stb_i, 
               wb_cyc_i      => wb_cyc_i, 
               wb_sel_i      => wb_sel_i, 
               wb_data_i     => wb_data_i,
               wb_data_o     => wb_data_o,
               wb_addr_i     => wb_addr_i,
               wb_ack_o      => wb_ack_o,
               wb_rty_o      => wb_rty_o,
               wb_err_o      => wb_err_o,

               rd_SPI3_i     => s_rd_SPI3,

               wr_data_o     => s_wr_data, 
               rd_data_i     => s_rd_data, 
               SR_m25p32_o   => s_SR_m25p32, 

               OP_i          => s_OP,
               FMI_o         => s_FMI
            );

end Behavioral;


