---------------------------------------------------------------------------
-- Copyright (c) 2012, TTTech Computertechnik AG
-- Project        : TTP NI
---------------------------------------------------------------------------
-- File           : test_utils_pkg.vhd
-- Author(s)      : Petr Kobiersky
-- Created        : March 12nd, 2012
---------------------------------------------------------------------------
-- Description    : Test Utilities
--
-- Package provides standard functions used for BFM and Test Writing.
--
---------------------------------------------------------------------------
-- $Id: test_utils_pkg.vhd 63551 2014-01-24 13:17:37Z kobiersky $
---------------------------------------------------------------------------
library IEEE, STD;
use IEEE.Std_Logic_1164.all;
use STD.textio.all;

-- -----------------------------------------------------------------------------
-- PACKAGE DECLARATION
-- -----------------------------------------------------------------------------
package test_utils_pkg is
   
   type tClkEdge is ( RISE,  -- Rising Edge
                      FALL); -- Falling Edge
   
   ----------------------------------------------------------------------------
   -- Compare Procedure
   -- Compare two vectors (when U is detected in ref vector, data
   -- comparison is ignored for the bit).
   ----------------------------------------------------------------------------
   function ucompare (   
      constant data : in std_logic_vector;     
      constant ref  : in std_logic_vector )
   return boolean;
  
   ----------------------------------------------------------------------------
   -- Return true when vector is UUUU
   ----------------------------------------------------------------------------
   function is_u (   
      constant data : in std_logic_vector)
   return boolean;

   ----------------------------------------------------------------------------
   -- IDLE Procedure
   -- Waits for specific number of clocks cycles (falling edge sensitive)
   ----------------------------------------------------------------------------
   procedure idle (   
     constant count   : in natural;         -- Number of clock period    
     signal   clock   : in std_logic;       -- Clock Signal       
     constant edge    : in tClkEdge := FALL -- Clock Edge            
   );

   ----------------------------------------------------------------------------
   -- IDLE Procedure
   -- Waits for specific number of clocks cycles (falling edge sensitive)
   -- plus additional absolute time.
   ----------------------------------------------------------------------------
   procedure idle (
     constant count    : in natural;         -- Number of clock period    
     signal   clock    : in std_logic;       -- Clock Signal       
     constant add_wait : in time;             -- Additional wait interval
     constant edge     : in tClkEdge := FALL -- Clock Edge  
   );

end test_utils_pkg;

-- -----------------------------------------------------------------------------
-- PACKAGE BODY 
-- -----------------------------------------------------------------------------

package body test_utils_pkg is
   ----------------------------------------------------------------------------
   -- Return true when vector is UUUU
   ----------------------------------------------------------------------------
   function is_u ( constant data : in std_logic_vector)
   return boolean is
      variable all_u : boolean := true;
   begin
      for i in 0 to data'length - 1 loop
         if data(i) /= 'U' then
            all_u := false;
            exit;
         end if;
      end loop;
      return all_u;
   end function is_u;


   ----------------------------------------------------------------------------
   -- Compare Procedure
   -- Compare two vectors (when U is detected in ref vector, data
   -- comparison is ignored for the bit).
   ----------------------------------------------------------------------------
   function ucompare (   
      constant data : in std_logic_vector;     
      constant ref  : in std_logic_vector )
   return boolean is
      variable match     : boolean := true;
   begin
      --Determine length 
      if data'length /= ref'length then
         match:=false;
      end if;
   
      --Compare (ignore 'U' bits)
      for i in 0 to ref'length - 1 loop
         if ref(i) /= 'U' then
            if data(i) /= ref(i) then
               match := false;
            end if;
         end if;
      end loop;
      
      return match;   
   end function ucompare;


   ----------------------------------------------------------------------------
   -- IDLE Procedure
   -- Waits for specific number of clocks cycles (falling edge sensitive)
   ----------------------------------------------------------------------------
   procedure idle (   
     constant count   : in natural;         -- Number of clock period    
     signal   clock   : in std_logic;       -- Clock Signal       
     constant edge    : in tClkEdge := FALL -- Clock Edge        
   ) is
   begin
       for i in 1 to count loop
          if edge = FALL then
            wait until falling_edge(clock);
          else
            wait until rising_edge(clock);
          end if;
       end loop;
       wait for 0 ns; -- Wait for delta cycle       
   end idle;   

   ----------------------------------------------------------------------------
   -- IDLE Procedure
   -- Waits for specific number of clocks cycles (falling edge sensitive)
   -- plus additional absolute time.
   ----------------------------------------------------------------------------
    procedure idle (
     constant count    : in natural;         -- Number of clock period    
     signal   clock    : in std_logic;       -- Clock Signal       
     constant add_wait : in time;            -- Additional wait interval
     constant edge     : in tClkEdge := FALL -- Clock Edge  
   ) is
   begin
       for i in 1 to count loop
          if edge = FALL then
            wait until falling_edge(clock);
          else
            wait until rising_edge(clock);
          end if;
       end loop;
       wait for add_wait;
   end idle;
 
end test_utils_pkg;
