--------------------------------------------------------------------------------
-- Title   : duplication testbench
-- Project : TimEX3
--------------------------------------------------------------------------------
-- Description :  Top-up monitor test bench
--------------------------------------------------------------------------------
-- File     : topup_monitor_tb.vhd
-- Revision : x.x.x
-- Created  : December 18, 2012
-- Updated  : December 18, 2012
--------------------------------------------------------------------------------
-- Author       : Jean-Paul Ricaud
-- Organization : Synchrotron Soleil
-- Web          : http://www.synchrotron-soleil.fr
-- Email        : jean-paul.ricaud@synchrotron-soleil.fr
--------------------------------------------------------------------------------
-- Copyright (C) 2012 - Synchrotron Soleil
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Modifications :
--
--------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

--------------------------------------------------------------------------------
--------------------------------- ENTITY ---------------------------------------
--------------------------------------------------------------------------------
entity topup_monitor_tb is
end entity topup_monitor_tb;

--------------------------------------------------------------------------------
------------------------------- ARCHITECTURE -----------------------------------
--------------------------------------------------------------------------------
architecture topup_monitor_tb of topup_monitor_tb is

  -- constants
  constant Period_1kHz   : TIME := 100.000 ps;
  constant Period_500mHz : TIME := 500.000 ps;
  constant Period_60MHz  : TIME := 16.667 ps;

  -- signals
  signal s_in0       : std_logic;
  signal s_in1       : std_logic;
  signal s_reset     : std_logic;
  signal s_clk1kHz   : std_logic;
  signal s_clk500mHz : std_logic;
  signal s_clk60MHz  : std_logic;
  signal s_State     : std_logic;
  signal s_Error             : std_logic_vector (1 downto 0);
  signal s_csw               : std_logic_vector (1 downto 0);
  signal s_maxPostTopUpDelay : std_logic_vector (31 downto 0); -- delay between post and pre top-up signals
  signal s_maxPreTopUpDelay  : std_logic_vector (31 downto 0); -- delay between pre and post top-up signals

  ----------------------------------------------------------------------------
  ----------------------------------------------------------------------------
  begin

  -- Reset
  DUT : entity work.topup_monitor (rtl_topup_monitor)
    port map (
      p_clk1kHz     => s_clk1kHz,
      p_clk60MHz    => s_clk60MHz,
      p_inTTL(0)    => s_in0,
      p_inTTL(1)    => s_in1,
      p_maxPostTopUpDelay => s_maxPostTopUpDelay, -- delay between post and pre top-up signals
      p_maxPreTopUpDelay  => s_maxPreTopUpDelay,  -- delay between pre and post top-up signals
      p_csw         => s_csw(1 downto 0),
      p_reset       => s_reset,
      p_State       => s_State, -- 0 : post top-up ; 1 : pre top-up
      p_topUpError  => s_Error  -- Error(0) : pre to post error ; Error(1) : post to pre error
    );

  -- Clock generator
  process
  begin
    s_clk1kHz <= '0';
    wait for (Period_1kHz / 2);
    s_clk1kHz <= '1';
    wait for (Period_1kHz / 2);
  end process;

  process
  begin
    s_clk500mHz <= '0';
    wait for (Period_500mHz / 2);
    s_clk500mHz <= '1';
    wait for (Period_500mHz / 2);
  end process;

  process
  begin
    s_clk60MHz <= '0';
    wait for (Period_60MHz / 2);
    s_clk60MHz <= '1';
    wait for (Period_60MHz / 2);
  end process;

  process
  begin
    -- Reset
    s_maxPostTopUpDelay <= X"00000007";
    s_maxPreTopUpDelay  <= X"00000009";
    s_csw(0) <= '0';
    s_csw(1) <= '0';
    s_in0    <= '0';
    s_in1    <= '0';
    s_reset  <= '0';
    wait for 10 ns;
    s_reset <= '1';
    wait for 10 ns;
    s_reset <= '0';
    wait for 10 ns;

    -- Get user defined delays
    wait for 7 ns;
    s_csw(0) <= '1';
    s_csw(1) <= '1';
    wait for Period_60MHz * 2;
    s_csw(0) <= '0';
    s_csw(1) <= '0';

    -- Top-up gating
    wait for 7 ns;
    s_in0 <= '1';
    wait for 1 ns;
    s_in0 <= '0';
    wait for 5 ns;
    s_in1 <= '1';
    wait for 1 ns;
    s_in1 <= '0';

    -- Change delays
    s_maxPostTopUpDelay <= X"00000004";
    s_maxPreTopUpDelay  <= X"00000003";
    wait for 7 ns;
    s_csw(0) <= '1';
    s_csw(1) <= '1';
    wait for Period_60MHz * 2;
    s_csw(0) <= '0';
    s_csw(1) <= '0';

    -- Top-up gating
    wait for 7 ns;
    s_in0 <= '1';
    wait for 10 ns;
    s_in0 <= '0';
    wait for 20 ns;
    s_in1 <= '1';
    wait for 10 ns;
    s_in1 <= '0';

    -- Change delays
    s_maxPostTopUpDelay <= X"00001068";
    s_maxPreTopUpDelay  <= X"000004B0";
    wait for 7 ns;
    s_csw(0) <= '1';
    s_csw(1) <= '1';
    wait for Period_60MHz * 2;
    s_csw(0) <= '0';
    s_csw(1) <= '0';

    -- Top-up gating
    wait for 7 ns;
    s_in0 <= '1';
    wait for 10 ns;
    s_in0 <= '0';
    wait for 20 ns;
    s_in1 <= '1';
    wait for 10 ns;
    s_in1 <= '0';

    -- *** END ***
    wait;
  end process;

  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------

end architecture topup_monitor_tb;
