--==============================================================================
-- CERN (BE-CO-HT)
-- Testbench for old repeater design
--==============================================================================
--
-- author: Theodor Stana (t.stana@cern.ch)
--
-- date of creation: 2013-02-28
--
-- version: 1.0
--
-- description: 
--
-- dependencies:
--
-- references:
-- 
--==============================================================================
-- GNU LESSER GENERAL PUBLIC LICENSE
--==============================================================================
-- This source file 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 2.1 of the License, or (at your
-- option) any later version. This source 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
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--==============================================================================
-- last changes:
--    2013-02-28   Theodor Stana     t.stana@cern.ch     File created
--==============================================================================
-- TODO: - 
--==============================================================================

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

use work.gencores_pkg.all;

entity testbench is
end entity testbench;


architecture behav of testbench is

  --============================================================================
  -- Constant declarations
  --============================================================================
  constant c_clk_per : time := 50 ns;
  constant c_reset_width : time := 31 ns;

  --============================================================================
  -- Component declarations
  --============================================================================
  component conv_pulse_gen is
    generic
    (
      -- Pulse width, in number of clk_i cycles
      -- Default pulse width (20 MHz clock): 1.2 us
      -- Minimum allowable pulse width (20 MHz clock): 1 us
      -- Maximum allowable pulse width (20 MHz clock): 2 us
      g_pwidth : natural range 20 to 40 := 24;

      -- Duty cycle divider: D = 1/g_duty_cycle_div
      g_duty_cycle_div : natural := 5
    );
    port
    (
      -- Clock and active-low reset inputs
      clk_i     : in  std_logic;
      rst_n_i   : in  std_logic;

      -- Glitch filter enable input
      -- '1' - Glitch filter disabled (glitch-sensitive, no output jitter)
      -- '0' - Glitch filter enabled (glitch-insensitive, with output jitter)
      gf_en_n_i : in  std_logic;

      -- Enable input, pulse generation is enabled when '1'
      en_i      : in  std_logic;

      -- Trigger input, has to be '1' to assure pulse output with delay no greater
      -- than internal gate delays.
      trig_a_i  : in  std_logic;

      -- Pulse output, active-high
      -- latency:
      --    glitch filter disabled: none
      --    glitch filter enabled: glitch filter length + 5 clk_i cycles
      pulse_o   : out std_logic
    );
  end component conv_pulse_gen;

  component pulse_gen_gp is
    port
    (
      -- Input clock and active-low reset
      clk_i    : in  std_logic;
      rst_n_i  : in  std_logic;

      -- Active high enable signal
      en_i     : in  std_logic;

      -- Delay, pulse width and frequency inputs, in number of clk_i cycles
      delay_i  : in  std_logic_vector(31 downto 0);
      pwidth_i : in  std_logic_vector(31 downto 0);
      freq_i   : in  std_logic_vector(31 downto 0);

      -- Output pulse signal
      pulse_o  : out std_logic
    );
  end component pulse_gen_gp;

  --============================================================================
  -- Signal declarations
  --============================================================================
  signal clk, clk4, rst_n, pulse, trig, lvl, lvl_n : std_logic := '0';
  signal trig_degl    : std_logic;
  signal trig_chan    : std_logic;
  signal trig_man     : std_logic;
  signal actual_trig  : std_logic := '0';
  signal actual_pulse : std_logic := '0';
  signal gf_en        : std_logic;
  signal gf_en_n      : std_logic;
  signal pgen_en      : std_logic;

--==============================================================================
--  architecture begin
--==============================================================================
begin


  -- DUT INSTANTIATION
  DUT: conv_pulse_gen
    generic map
    (
      g_pwidth         => 24,
      g_duty_cycle_div => 500
    )
    port map
    (
      clk_i     => clk,
      rst_n_i   => rst_n,
      gf_en_n_i => gf_en_n,
      en_i      => '1',
      trig_a_i  => actual_trig,
      pulse_o   => pulse
    );

  -- CLOCK GENERATION
  p_clk: process
  begin
    clk <= not clk;
    wait for c_clk_per/2;
  end process p_clk;

  -- SECOND CLOCK GENERATION
  p_clk4: process
  begin
    clk4 <= not clk4;
    wait for 2 ns;
  end process p_clk4;

  -- RESET GENERATION
  p_rst_n: process
  begin
    rst_n <= '0';
    wait for c_reset_width;
    rst_n <= '1';
    wait;
  end process p_rst_n;

  -- PULSE GENERATOR FOR TRIGGER
  cmp_pulse_gen : pulse_gen_gp
  port map
  (
    clk_i    => clk4,
    rst_n_i  => rst_n,
    en_i     => pgen_en,
    delay_i  => (others => '0'),
    pwidth_i => x"0000012c",
    freq_i   => x"000249f0",
    pulse_o  => trig
  );

  -- Glitch filter instantiation
  cmp_gf : gc_glitch_filt
    generic map
    (
      g_len => 1
    )
    port map
    (
      clk_i   => clk,
      rst_n_i => rst_n,
      dat_i   => trig,
      dat_o   => trig_degl
    );

  -- Trigger signal
  trig_chan  <= trig when gf_en_n = '1' else
                trig_degl;
  actual_trig <= trig_chan or trig_man;

  -- Glitch filter enable
  gf_en_n <= '0';

  -- manual trigger stimuli
  p_man_trig : process
  begin
    trig_man <= '0';
    pgen_en  <= '0';
    wait for 10 us;
    trig_man <= '1';
    wait for c_clk_per;
    trig_man <= '0';
    wait for 10 us;
    trig_man <= '1';
    wait for c_clk_per;
    trig_man <= '0';
    wait for 10 us;
    pgen_en <= '1';
--    wait for 30 us;
--    pgen_en <= '0';
--    wait for 10 us;
--    trig_man <= '1';
--    wait for c_clk_per;
--    trig_man <= '0';
--    wait for 10 us;
--    pgen_en <= '1';
    wait;
  end process;

end architecture behav;
--==============================================================================
--  architecture end
--==============================================================================
