--SINGLE_FILE_TAG
-------------------------------------------------------------------------------
-- wait_states.vhd - entity/architecture pair
-------------------------------------------------------------------------------
--
--  ***************************************************************************
--  **  Copyright(C) 2003 by Xilinx, Inc. All rights reserved.               **
--  **                                                                       **
--  **  This text contains proprietary, confidential                         **
--  **  information of Xilinx, Inc. , is distributed by                      **
--  **  under license from Xilinx, Inc., and may be used,                    **
--  **  copied and/or disclosed only pursuant to the terms                   **
--  **  of a valid license agreement with Xilinx, Inc.                       **
--  **                                                                       **
--  **  Unmodified source code is guaranteed to place and route,             **
--  **  function and run at speed according to the datasheet                 **
--  **  specification. Source code is provided "as-is", with no              **
--  **  obligation on the part of Xilinx to provide support.                 **
--  **                                                                       **
--  **  Xilinx Hotline support of source code IP shall only include          **
--  **  standard level Xilinx Hotline support, and will only address         **
--  **  issues and questions related to the standard released Netlist        **
--  **  version of the core (and thus indirectly, the original core source). **
--  **                                                                       **
--  **  The Xilinx Support Hotline does not have access to source            **
--  **  code and therefore cannot answer specific questions related          **
--  **  to source HDL. The Xilinx Support Hotline will only be able          **
--  **  to confirm the problem in the Netlist version of the core.           **
--  **                                                                       **
--  **  This copyright and support notice must be retained as part           **
--  **  of this text at all times.                                           **
--  ***************************************************************************
--
-------------------------------------------------------------------------------
-- Filename:        wait_states.vhd
-- Version:         v1.10b
-- Description:     Wait State calculator for memory controller
--                  Calculates the wait states and recovery wait states for
--                  the addressed memory bank
--
-------------------------------------------------------------------------------
-- Structure:   
--                  emc.vhd
--                      -- addr_counter_mux.vhd
--                      -- data_path.vhd
--                      -- io_registers.vhd
--                      -- mem_state_machine.vhd
--                      -- select_param.vhd
--                      -- wait_states.vhd
-------------------------------------------------------------------------------
-- Author:      DAB
-- History:
--  DAB             11-28-2001      
-- ^^^^^^
--      First version of wait state generator.
-- ~~~~~~
--  ALS            11-28-2002
-- ^^^^^^
--  Version 1.10.a created to include bus width/mem data width matching.
-- ~~~~~~
--   ALS           03/10/03    
-- ^^^^^^
--  Version 1.10.b created to include a generic to include/exclude negedge 
--  io registers
-- ~~~~~~
-------------------------------------------------------------------------------
-- Naming Conventions:
--      active low signals:                     "*_n"
--      clock signals:                          "clk", "clk_div#", "clk_#x" 
--      reset signals:                          "rst", "rst_n" 
--      generics:                               "C_*" 
--      user defined types:                     "*_TYPE" 
--      state machine next state:               "*_ns" 
--      state machine current state:            "*_cs" 
--      combinatorial signals:                  "*_cmb" 
--      pipelined or register delay signals:    "*_d#" 
--      counter signals:                        "*cnt*"
--      clock enable signals:                   "*_ce" 
--      internal version of output port         "*_i"
--      device pins:                            "*_pin" 
--      ports:                                  - Names begin with Uppercase 
--      processes:                              "*_PROCESS" 
--      component instantiations:               "<ENTITY_>I_<#|FUNC>
-------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_signed.all;

--library emc_common_v1_10_b;
--use emc_common_v1_10_a.all;

-------------------------------------------------------------------------------
-- Definition of Generics:
--      C_NUM_BANKS_MEM         -- number of memory banks 
--      C_RD_SLOW_(0:7)         -- memory bank (0:7) slow read access clocks
--      C_RD_FAST_(0:7)         -- memory bank (0:7) fast read access clocks
--      C_WR_SLOW_(0:7)         -- memory bank (0:7) slow write cycle clocks
--      C_WR_FAST_(0:7)         -- memory bank (0:7) fast write cycle clocks
--      C_RD_RECOVERY_(0:7)     -- memory bank (0:7) read recovery clocks
--      C_WR_RECOVERY_(0:7)     -- memory bank (0:7) write recovery clocks
--
-- Definition of Ports:
--  -- inputs
--      Bus2IP_Mem_CS           -- chip selects for memory banks
--                                 indicates which memory bank is being accessed
--      Fast_Slow_Select        -- fast/slow select for addressed memory bank   
--      RNW                     -- read not write
--
--  -- outputs
--      Mem_Wait_States         -- wait state clock cycles for addressed 
--                                 memory bank    
--      Recover_Wait_States     -- recovery wait state clock cycles for 
--                                 address memory bank
---------------------------------------------------------------------------

-----------------------------------------------------------------------------
-- Entity section
-----------------------------------------------------------------------------

entity Wait_States is
  generic (
    C_NUM_BANKS_MEM  : integer range 1 to 8 := 8;
    C_RD_SLOW_0      : integer := 14;
    C_RD_FAST_0      : integer := 4;
    C_WR_SLOW_0      : integer := 13;
    C_WR_FAST_0      : integer := 2;
    C_RD_RECOVERY_0  : integer := 21;
    C_WR_RECOVERY_0  : integer := 17;
    C_RD_SLOW_1      : integer := 14;
    C_RD_FAST_1      : integer := 4;
    C_WR_SLOW_1      : integer := 13;
    C_WR_FAST_1      : integer := 2;
    C_RD_RECOVERY_1  : integer := 21;
    C_WR_RECOVERY_1  : integer := 17;
    C_RD_SLOW_2      : integer := 4;
    C_RD_FAST_2      : integer := 26;
    C_WR_SLOW_2      : integer := 6;
    C_WR_FAST_2      : integer := 23;
    C_RD_RECOVERY_2  : integer := 12;
    C_WR_RECOVERY_2  : integer := 7;
    C_RD_SLOW_3      : integer := 30;
    C_RD_FAST_3      : integer := 27;
    C_WR_SLOW_3      : integer := 2;
    C_WR_FAST_3      : integer := 1;
    C_RD_RECOVERY_3  : integer := 28;
    C_WR_RECOVERY_3  : integer := 15;
    C_RD_SLOW_4      : integer := 12;
    C_RD_FAST_4      : integer := 19;
    C_WR_SLOW_4      : integer := 3;
    C_WR_FAST_4      : integer := 7;
    C_RD_RECOVERY_4  : integer := 23;
    C_WR_RECOVERY_4  : integer := 6;
    C_RD_SLOW_5      : integer := 17;
    C_RD_FAST_5      : integer := 22;
    C_WR_SLOW_5      : integer := 23;
    C_WR_FAST_5      : integer := 24;
    C_RD_RECOVERY_5  : integer := 8;
    C_WR_RECOVERY_5  : integer := 5;
    C_RD_SLOW_6      : integer := 29;
    C_RD_FAST_6      : integer := 5;
    C_WR_SLOW_6      : integer := 13;
    C_WR_FAST_6      : integer := 17;
    C_RD_RECOVERY_6  : integer := 28;
    C_WR_RECOVERY_6  : integer := 4;
    C_RD_SLOW_7      : integer := 24;
    C_RD_FAST_7      : integer := 16;
    C_WR_SLOW_7      : integer := 7;
    C_WR_FAST_7      : integer := 26;
    C_RD_RECOVERY_7  : integer := 12;
    C_WR_RECOVERY_7  : integer := 2
    );   
  port (              
    Bus2IP_Mem_CS       : in  std_logic_vector(0 to C_NUM_BANKS_MEM-1);
    Fast_Slow_Select    : in  std_logic_vector(0 to C_NUM_BANKS_MEM-1);
    RNW                 : in  std_logic;
    Mem_Wait_States     : out std_logic_vector(0 to 4);
    Recover_Wait_States : out std_logic_vector(0 to 4)  -- Recovery time WS
    );
end entity Wait_States;

-------------------------------------------------------------------------------
-- Architecture section
-------------------------------------------------------------------------------

architecture IMP of Wait_States is

type int1_array_type is array (0 to 3) of integer;
type int2_array_type is array (0 to 7) of int1_array_type;
type int3_array_type is array (0 to 1) of integer;
type int4_array_type is array (0 to 7) of int3_array_type;

signal rw_wait_states    : int1_array_type;
signal rec_wait_states   : int3_array_type;
signal fast_slow_sel_sig : std_logic;
signal final_select      : std_logic_vector(0 to 1);

constant rw_wait_state_array : int2_array_type :=
    ((C_WR_SLOW_0,C_WR_FAST_0,C_RD_SLOW_0,C_RD_FAST_0),     
     (C_WR_SLOW_1,C_WR_FAST_1,C_RD_SLOW_1,C_RD_FAST_1),     
     (C_WR_SLOW_2,C_WR_FAST_2,C_RD_SLOW_2,C_RD_FAST_2),     
     (C_WR_SLOW_3,C_WR_FAST_3,C_RD_SLOW_3,C_RD_FAST_3),     
     (C_WR_SLOW_4,C_WR_FAST_4,C_RD_SLOW_4,C_RD_FAST_4),     
     (C_WR_SLOW_5,C_WR_FAST_5,C_RD_SLOW_5,C_RD_FAST_5),     
     (C_WR_SLOW_6,C_WR_FAST_6,C_RD_SLOW_6,C_RD_FAST_6),     
     (C_WR_SLOW_7,C_WR_FAST_7,C_RD_SLOW_7,C_RD_FAST_7)); 

constant rec_wait_state_array : int4_array_type := 
    ((C_WR_RECOVERY_0,C_RD_RECOVERY_0),
     (C_WR_RECOVERY_1,C_RD_RECOVERY_1),
     (C_WR_RECOVERY_2,C_RD_RECOVERY_2),
     (C_WR_RECOVERY_3,C_RD_RECOVERY_3),
     (C_WR_RECOVERY_4,C_RD_RECOVERY_4),
     (C_WR_RECOVERY_5,C_RD_RECOVERY_5),
     (C_WR_RECOVERY_6,C_RD_RECOVERY_6),
     (C_WR_RECOVERY_7,C_RD_RECOVERY_7));
     
begin
                           
SELECT_TIMING_PROCESS: process (Fast_Slow_Select,
                                Bus2IP_Mem_CS) is
begin
  rw_wait_states    <= rw_wait_state_array(0);
  rec_wait_states   <= rec_wait_state_array(0);
  fast_slow_sel_sig <= '0';
  for i in 0 to C_NUM_BANKS_MEM-1 loop
    if Bus2IP_Mem_CS(i)='1' then
      rw_wait_states    <= rw_wait_state_array(i);
      fast_slow_sel_sig <= Fast_Slow_Select(i);
      rec_wait_states   <= rec_wait_state_array(i);
    end if;
  end loop;
end process SELECT_TIMING_PROCESS;

final_select <= (RNW,fast_slow_sel_sig);

SELECT_FAST_SLOW_PROCESS: process (final_select,rw_wait_states) is
begin
  Mem_Wait_States <= "00000";
  for i in 0 to 3 loop
    if Conv_std_logic_vector(i,2) = final_select then
      Mem_Wait_States <= Conv_std_logic_vector(rw_wait_states(i),5);
    end if;
  end loop;
  if final_select(0) = '1' then -- Read when final_select(0) = '1'
    Recover_Wait_States <= Conv_std_logic_vector(rec_wait_states(1),5);
  else
    Recover_Wait_States <= Conv_std_logic_vector(rec_wait_states(0),5);
  end if;
end process SELECT_FAST_SLOW_PROCESS;

end architecture IMP;
