--==============================================================================
-- CERN (BE-CO-HT)
-- TTL-RS485 pkg package
--==============================================================================

--==============================================================================
-- 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
--==============================================================================

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

use work.wishbone_pkg.all;
use work.genram_pkg.all;
use work.print_pkg.all;


package testbench_pkg is

  --============================================================================
  -- Constant declarations
  --============================================================================
  
  -- Clock periods
  constant c_clk_20_per   : time := 50 ns;
  constant c_clk_125_per  : time :=  8 ns;
  constant c_reset_width  : time := 200 ns;

  
  -- DUT configuration (generics):
  constant c_nr_chans     : integer := 6;
  constant c_nr_inv_chans : integer := 4;
  constant c_board_id     : std_logic_vector(31 downto 0) := x"54424c4f";
  constant c_gwvers       : std_logic_vector(7  downto 0) :=x"40";

   -- Number of I2C masters and slaves for the I2C bus model
  constant c_nr_masters : positive := 1;
  constant c_nr_slaves  : positive := 1;

  --============================================================================
  -- Types declarations
  --============================================================================
  type t_i2c_master_in is record
    i2c_master_start                  : std_logic;  
    i2c_master_rdwr                   : std_logic;
    i2c_master_slv_addr               : std_logic_vector(6 downto 0);
    i2c_master_reg_addr               : std_logic_vector(31 downto 0);
    i2c_master_send_val               : std_logic_vector(31 downto 0);
  end record;

  type t_i2c_master_out is record
    i2c_master_ready                  : std_logic;
    i2c_master_finish                 : std_logic;
    i2c_master_rcvd_val               : std_logic_vector(31 downto 0);
  end record;


  --============================================================================
  -- Components declarations
  --============================================================================
  component conv_ttl_rs485 is
  port
  (
    -- Clocks
    clk_20_i                : in  std_logic;
    clk_125_p_i             : in  std_logic;
    clk_125_n_i             : in  std_logic;

    -- I2C interface
    scl_i                   : in  std_logic;
    scl_o                   : out std_logic;
    scl_en_o                : out std_logic;
    sda_i                   : in  std_logic;
    sda_o                   : out std_logic;
    sda_en_o                : out std_logic;

    -- VME interface
    vme_sysreset_n_i        : in  std_logic;
    vme_ga_i                : in  std_logic_vector(4 downto 0);
    vme_gap_i               : in  std_logic;

    -- PCB version recognition
    pcbrev_i				: in std_logic_vector(5 downto 0);

    -- Channel enable
    global_oen_o            : out std_logic;
    ttl_oen_o               : out std_logic;
    inv_oen_o               : out std_logic;
    rs485_oen_o             : out std_logic;

    -- Front panel channels
    ttl_n_i                 : in  std_logic_vector(5 downto 0);
    ttl_o                   : out std_logic_vector(5 downto 0);
    inv_n_i                 : in  std_logic_vector(3 downto 0);
    inv_o                   : out std_logic_vector(3 downto 0);

    -- Rear panel channels
    rs485_n_i               : in  std_logic_vector(5 downto 0);
    rs485_fs_n_i            : in  std_logic_vector(5 downto 0);
    rs485_o                 : out std_logic_vector(5 downto 0);

    -- Rear input and output termination lines
    iterm_en_o              : out std_logic_vector(5 downto 0);
    oterm_en_o              : out std_logic_vector(5 downto 0);

    -- Channel leds
    led_front_n_o           : out std_logic_vector(5 downto 0);
    led_front_inv_n_o       : out std_logic_vector(3 downto 0);
    led_rear_n_o            : out std_logic_vector(5 downto 0);

    -- SPI interface to on-board flash chip
    flash_cs_n_o            : out std_logic;
    flash_sclk_o            : out std_logic;
    flash_mosi_o            : out std_logic;
    flash_miso_i            : in  std_logic;

    -- PLL DACs
    -- 20 MHz VCXO control
    dac20_din_o             : out std_logic;
    dac20_sclk_o            : out std_logic;
    dac20_sync_n_o          : out std_logic;
    -- 125 MHz clock generator control
    dac125_din_o            : out std_logic;
    dac125_sclk_o           : out std_logic;
    dac125_sync_n_o         : out std_logic;

    -- SFP lines
    sfp_los_i               : in    std_logic;
    sfp_present_i           : in    std_logic;
    sfp_rate_select_o       : out   std_logic;
    sfp_scl_b               : inout std_logic;
    sfp_sda_b               : inout std_logic;
    sfp_tx_disable_o        : out   std_logic;
    sfp_tx_fault_i          : in    std_logic;

    -- Thermometer data port
    thermometer_b           : inout std_logic;

    -- Switches
    sw_gp_n_i               : in   std_logic_vector(7 downto 0);
    sw_multicast_n_i        : in   std_logic_vector(3 downto 0);

    -- RTM lines
    rtmm_i                  : in  std_logic_vector(2 downto 0);
    rtmp_i                  : in  std_logic_vector(2 downto 0);

    -- Front panel bicolor LEDs
    led_ctrl0_o             : out std_logic;
    led_ctrl0_oen_o         : out std_logic;
    led_ctrl1_o             : out std_logic;
    led_ctrl1_oen_o         : out std_logic;
    led_gp_2_4_o            : out std_logic;
    led_gp_1_3_o            : out std_logic;
    led_oterm_wr_o          : out std_logic;
    led_iterm_syserror_o    : out std_logic;
    led_gf_syspw_o          : out std_logic;
    led_ttl_i2c_o           : out std_logic
  );
end component conv_ttl_rs485;

  -- procedure read_i2c (signal i2c_m_out  : in  t_i2c_master_out;
                      -- signal i2c_m_in   : out t_i2c_master_in;
                      -- signal slv_addr : in  std_logic_vector( 6 downto 0);
                      -- signal reg_addr : in  std_logic_vector(31 downto 0);
                      -- signal rcvd_val   : out std_logic_vector(31 downto 0));


  procedure generate_pulses (signal pulses_n_out : out std_logic_vector (c_nr_chans-1 downto 0);
                             nb_of_pulses        : in natural;
                             ns_on               : in time;
                             ns_off              : in time);

end testbench_pkg;
package body testbench_pkg is 
--==================================================================================================
--  Procedures
--==================================================================================================
  procedure settings_config (signal sw_gp_n_in  : out std_logic_vector(7 downto 0);
                             signal sw_other_in : out std_logic_vector(31 downto 0);
                             signal pcbrev      : out std_logic_vector(5 downto 0);
                             signal rtmm_in     : out std_logic_vector(2 downto 0)) is
  begin
    sw_gp_n_in(0)           <= '1'; -- disable glitch filter ?
    sw_gp_n_in(1)           <= '1'; --
    sw_gp_n_in(7 downto 2)  <= (others => '0');
    sw_other_in             <= (others => '0');
    pcbrev                  <= "111100";
    rtmm_in                 <= (others => '0');
  end procedure;

----------------------------------------------------------------------------------------------------
  procedure generate_pulses (signal pulses_n_out : out std_logic_vector (c_nr_chans-1 downto 0);
                             nb_of_pulses        : in natural;
                             ns_on               : in time;
                             ns_off              : in time) is

    variable numb_cnt : natural;
    begin
      numb_cnt := 0;
      while not(numb_cnt = nb_of_pulses) loop
        pulses_n_out <= (others => '1');
        wait for ns_off; --min period is 240us??
        pulses_n_out <= (others => '0');
        wait for ns_on; 
        pulses_n_out <= (others => '1');
        numb_cnt:= numb_cnt + 1;
      end loop;
  end procedure generate_pulses;
 
end;


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

