--===========================================================================
-- This file was written by Luca Giacotto, Ph.D. candidate at the University
-- J. Fourier, Grenoble, France, and is a modified version of the original
-- file "IBIS_basic_IO.vhd" written by Arpad Muranyi, Intel Corporation.
-- The original "disclaimer" is reproduced here and should be considered
-- valid for this modified version also.
--
-- In particular, this file is provided "as is" with no warranties whatsoever,
-- including any warranty of merchantability, noninfringement, fitness for
-- any particular purpose, or any warranty otherwise arising out of any
-- proposal, specification or sample.  The author disclaim all liability,
-- including liability or infringement of any proprietary rights, including
-- rights to use the information in this file.  No license, express or
-- implied, by estoppel or otherwise, to any intellectual property rights is
-- granted herein.
--===========================================================================
-- ORIGINAL DISCLAIMER --
--===========================================================================
-- This file was written by Arpad Muranyi, Intel Corporation.  It does not
-- contain any confidential or proprietary information, and it is made
-- available to the public with the intent of promoting the usage of the
-- Multi-Lingual Extensions of the IBIS specification and to help pave the
-- way for more accurate behavioral I/O buffer models and simulations.  This
-- file may be used, modified, and distributed without any limitations;
-- however, this file is provided "as is" with no warranties whatsoever,
-- including any warranty of merchantability, noninfringement, fitness for
-- any particular purpose, or any warranty otherwise arising out of any
-- proposal, specification or sample.  Intel and the author disclaim all
-- liability, including liability or infringement of any proprietary rights,
-- including rights to use the information in this file.  No license,
-- express or implied, by estoppel or otherwise, to any intellectual
-- property rights is granted herein.
--===========================================================================
-- END OF ORIGINAL DISCLAIMER --
--===========================================================================
--===========================================================================
--===========================================================================
--===========================================================================
-- GENERAL NOTE
--
-- The code contained in this file reflects the intent to achieve a high
-- degree of modularity.  Thus the subdivision into several design entities.
-- However, the limitations in the VHDL-AMS simulator (free promotional
-- software) that was used to develop this model made a significant impact
-- on the result.  In particular, this code has been developed without the
-- following features of the VHDL-AMS language:
--
-- *) shared-variables,
-- *) access types;
-- *) record types;
-- *) multidimensional array types;
-- *) File I/O;
-- *) and some other minor features.
--===========================================================================
--===========================================================================
--===========================================================================
--===========================================================================
-- Features: this package contains some type declarations.
--
-- To be done: -
--
--===========================================================================
library IEEE;
use IEEE.math_real.all;
use IEEE.std_logic_1164.all;
library IEEE_proposed;
use IEEE_proposed.electrical_systems.all;
use IEEE_proposed.energy_systems.all;
--===========================================================================
package some_types is
   -- I need to declare these types in a package, because I
   -- use them to declare "ports" and/or "generics".
   type corner_type is (Typ, Min, Max); 
   type Ccomp_type is (C_comp, C_comp4, NL_C_comp, NL_C_comp4);  -- to choose among die-capacitance
                                                                 -- modeling strategies
   constant minus2plus : integer := -1;  -- to define the direction of the
   constant plus2minus : integer := 1;   -- output current from the IV elements
end package some_types;
--===========================================================================
--===========================================================================
--===========================================================================
--===========================================================================
-- Features: this package contains all the functions. Most of
--           them are called only in the initialization phase.
--
-- To be done: -
--
--===========================================================================
library IEEE;
use IEEE.math_real.all;
use IEEE.std_logic_1164.all;
library IEEE_proposed;
use IEEE_proposed.electrical_systems.all;
use IEEE_proposed.energy_systems.all;
use work.some_types.all;
--===========================================================================
package IBIS_Kernel_functions is
  function Lookup (Extrapolation : in string := "IV";
                   X             : in real;
                   Ydata         : in real_vector;
                   Xdata         : in real_vector) return real; 
  ---------------------------------------------------------------------------
  function Common_time (Max_dt : real := 1.0e-12;
                        Twfm_1 : in real_vector;
                        Twfm_2 : in real_vector;
                        Twfm_3 : in real_vector;
                        Twfm_4 : in real_vector) return real_vector;
  ---------------------------------------------------------------------------
  function Common_wfm (New_t : in real_vector;
                       Vwfm  : in real_vector;
                       Twfm  : in real_vector) return real_vector;
  ---------------------------------------------------------------------------
  function Coeff (Edge     : in string;
                  Vwfm_pu  : in real_vector;
                  Vwfm_pd  : in real_vector;
                  Twfm     : in real_vector;
                  Rfx_pu   : in real;
                  Rfx_pd   : in real;
                  Vfx_pu   : in real;
                  Vfx_pd   : in real;
                  Iiv_pu   : in real_vector;
                  Viv_pu   : in real_vector;
                  Iiv_pd   : in real_vector;
                  Viv_pd   : in real_vector;
                  V_pu_ref : in real;
                  V_pd_ref : in real;
                  C_comp   : in real) return real_vector;
end package IBIS_Kernel_functions;
--===========================================================================
package body IBIS_Kernel_functions is
  function Lookup (Extrapolation : in string := "IV";
                   X             : in real;
                   Ydata         : in real_vector;
                   Xdata         : in real_vector) return real is 
  ---------------------------------------------------------------------------
  -- This function is basically the equivalent of a PWL function in SPICE.
  -- It returns "Y" that corresponds to "X" in the "Ydata" "Xdata" input pair
  -- using linear interpolation.
  --
  -- If the "X" input value lies outside the range of "Xdata", the returned
  -- "Y" value will either be equal to the first or last point in "Ydata",
  -- or it will be calculated using the slope between the first or last two
  -- points of "Ydata".  The extrapolation method is determined by the string
  -- in "Extrapolation".  "Vt" selects the repeated points method, "IV"
  -- selects the last slopes method.
  --
  -- (The original code of this function was received from Mentor Graphics,
  -- modifications written by Arpad Muranyi, Intel Corporation).
  ---------------------------------------------------------------------------
    variable xvalue, yvalue, m : real;
    variable start, fin, mid   : integer; 
  ---------------------------------------------------------------------------
  begin
    -------------------------------------------------------------------------
    -- Handle cases when "X" is outside the range of "Xdata"
    -------------------------------------------------------------------------
    if (Extrapolation = "IV") and (X <= Xdata(0)) then
      m := (Ydata(1) - Ydata(0)) / (Xdata(1) - Xdata(0));
      yvalue := Ydata(0) + m * (X - Xdata(0));
      return yvalue;

    elsif (Extrapolation = "Vt") and (X <= Xdata(0)) then
      yvalue := Ydata(0);
      return yvalue;

    elsif (Extrapolation = "IV") and (X >= Xdata(Xdata'right)) then
      m := (Ydata(Ydata'right) - Ydata(Ydata'right - 1)) / (Xdata(Xdata'right) - Xdata(Xdata'right - 1));
      yvalue := Ydata(Ydata'right) + m * (X - Xdata(Xdata'right));
      return yvalue;

    elsif (Extrapolation = "Vt") and (X >= Xdata(Xdata'right)) then
      yvalue := Ydata(Ydata'right);
      return yvalue;
    -------------------------------------------------------------------------
    -- Handle cases when "X" is in the range of "Xdata"
    -------------------------------------------------------------------------
    else
      start:= 0;
      fin := Xdata'right;

      while  start <= fin  loop
        mid := (start + fin) / 2; 

        if Xdata(mid) < X then
          start := mid + 1;
        else fin := mid - 1;
        end if;  

      end loop; 
                       
      if Xdata(mid) > X then
        mid := mid - 1; 
      end if;
      -----------------------------------------------------------------------
      -- Find "Y" by linear interpolation
      -----------------------------------------------------------------------
      yvalue := Ydata(mid) + (X - Xdata(mid)) * (Ydata(mid+1) - Ydata(mid)) / (Xdata(mid+1) - Xdata(mid));
      return yvalue;
    -------------------------------------------------------------------------
    end if;
    -------------------------------------------------------------------------
  end function Lookup;
--===========================================================================
--===========================================================================
  function Find_common_length (Max_dt : real := 1.0e-12;
                               Twfm_1 : in real_vector;
                               Twfm_2 : in real_vector;
                               Twfm_3 : in real_vector;
                               Twfm_4 : in real_vector) return integer is
  ---------------------------------------------------------------------------
  -- This function finds the total number of points needed for having a
  -- common time axis for all Vt curves, such that the maximum delta time
  -- between each time point doesn't exceed the value provided in "Max_dt".
  ---------------------------------------------------------------------------
  variable Common_length : integer := 0;
  variable Return_val    : integer := 0;

  variable index_1       : integer := Twfm_1'left;
  variable index_2       : integer := Twfm_2'left;
  variable index_3       : integer := Twfm_3'left;
  variable index_4       : integer := Twfm_4'left;

  variable new_index_1   : integer := Twfm_1'left;
  variable new_index_2   : integer := Twfm_2'left;
  variable new_index_3   : integer := Twfm_3'left;
  variable new_index_4   : integer := Twfm_4'left;

  variable old_t         : real    := 0.0;
  variable new_t         : real    := 0.0;
  variable remainder     : real    := 0.0;
  variable min_dt        : real    := 1.0e-3;  -- This sets the size of the
                                               -- roundoff error relative to
                                               -- "Max_dt"
  ---------------------------------------------------------------------------
  begin
  ---------------------------------------------------------------------------
  -- Put the earliest time value of all given time vectors into "old_t"
  ---------------------------------------------------------------------------
    old_t := Twfm_1(Twfm_1'left);
    if (Twfm_2(Twfm_2'left) < old_t) then old_t := Twfm_2(Twfm_2'left);
    end if;
    if (Twfm_3(Twfm_3'left) < old_t) then old_t := Twfm_3(Twfm_3'left);
    end if;
    if (Twfm_4(Twfm_4'left) < old_t) then old_t := Twfm_4(Twfm_4'left);
    end if;
  ---------------------------------------------------------------------------
  -- Put the latest time value of all given time vectors into "new_t"
  ---------------------------------------------------------------------------
    new_t := Twfm_1(Twfm_1'right);
    if (Twfm_2(Twfm_2'right) > new_t) then new_t := Twfm_2(Twfm_2'right);
    end if;
    if (Twfm_3(Twfm_3'right) > new_t) then new_t := Twfm_3(Twfm_3'right);
    end if;
    if (Twfm_4(Twfm_4'right) > new_t) then new_t := Twfm_4(Twfm_4'right);
    end if;
    new_t := new_t;
  ---------------------------------------------------------------------------
  -- Loop until latest time value is reached in each given time vector
  ---------------------------------------------------------------------------
  while (old_t < new_t) loop
    -------------------------------------------------------------------------
    -- Find which given time vector(s) have the lowest time value and
    -- advance their temporary indexes
    -------------------------------------------------------------------------
    if (Twfm_1(index_1) <= old_t) then new_index_1 := index_1 + 1;
    end if;
    if (Twfm_2(index_2) <= old_t) then new_index_2 := index_2 + 1;
    end if;
    if (Twfm_3(index_3) <= old_t) then new_index_3 := index_3 + 1;
    end if;
    if (Twfm_4(index_4) <= old_t) then new_index_4 := index_4 + 1;
    end if;
    -------------------------------------------------------------------------
    -- Find the lowest value at the new indexes in the given vector(s) and
    -- update indexes for next iteration
    -------------------------------------------------------------------------
    if (new_index_1 <= Twfm_1'right) then
      if (Twfm_1(new_index_1) < new_t) then new_t := Twfm_1(new_index_1);
      end if;
      index_1 := new_index_1;
    end if;
    if (new_index_2 <= Twfm_2'right) then
      if (Twfm_2(new_index_2) < new_t) then new_t := Twfm_2(new_index_2);
      end if;
      index_2 := new_index_2;
    end if;
    if (new_index_3 <= Twfm_3'right) then
      if (Twfm_3(new_index_3) < new_t) then new_t := Twfm_3(new_index_3);
      end if;
      index_3 := new_index_3;
    end if;
    if (new_index_4 <= Twfm_4'right) then
      if (Twfm_4(new_index_4) < new_t) then new_t := Twfm_4(new_index_4);
      end if;
      index_4 := new_index_4;
    end if;
    -------------------------------------------------------------------------
    -- Calculate how many additional points are needed between the given
    -- points to satisfy the "Max_dt" separation criteria.  Note: the extra
    -- logic is needed due to floating point inaccuracies.
    -------------------------------------------------------------------------
    Common_length := Common_length + integer(ceil((new_t-old_t)/Max_dt));

    remainder := "mod"((new_t-old_t),Max_dt);
    if (remainder < (min_dt * Max_dt)) and (remainder > 0.0) then
      Common_length := Common_length - 1;
    end if;
    -------------------------------------------------------------------------
    -- Update variables for next iteration
    -------------------------------------------------------------------------
    old_t   := new_t;

    new_t := Twfm_1(Twfm_1'right);
    if (Twfm_2(Twfm_2'right) > new_t) then new_t := Twfm_2(Twfm_2'right);
    end if;
    if (Twfm_3(Twfm_3'right) > new_t) then new_t := Twfm_3(Twfm_3'right);
    end if;
    if (Twfm_4(Twfm_4'right) > new_t) then new_t := Twfm_4(Twfm_4'right);
    end if;
    new_t := new_t;
  ---------------------------------------------------------------------------
  end loop; 
  ---------------------------------------------------------------------------
  return Common_length;
  end function Find_common_length;
--===========================================================================
--===========================================================================
  function Common_time (Max_dt : real := 1.0e-12;
                        Twfm_1 : in real_vector;
                        Twfm_2 : in real_vector;
                        Twfm_3 : in real_vector;
                        Twfm_4 : in real_vector) return real_vector is
  ---------------------------------------------------------------------------
  -- This function generates a vector that serves as a common time axis for
  -- all Vt curves, such that the maximum delta time between each time point
  -- doesn't exceed the value provided in "Max_dt".
  ---------------------------------------------------------------------------
  variable New_time     : real_vector(0 to Find_common_length(Max_dt, Twfm_1, Twfm_2, Twfm_3, Twfm_4)) := (others => 0.0);

  variable index        : integer := 0;
  variable extra_start  : integer := 0;
  variable extra_points : integer := 0;

  variable index_1      : integer := Twfm_1'left;
  variable index_2      : integer := Twfm_2'left;
  variable index_3      : integer := Twfm_3'left;
  variable index_4      : integer := Twfm_4'left;

  variable new_index_1  : integer := Twfm_1'left;
  variable new_index_2  : integer := Twfm_2'left;
  variable new_index_3  : integer := Twfm_3'left;
  variable new_index_4  : integer := Twfm_4'left;

  variable old_t        : real    := 0.0;
  variable new_t        : real    := 0.0;
  variable remainder    : real    := 0.0;
  variable min_dt       : real    := 1.0e-3;   -- This sets the size of the
                                               -- roundoff error relative to
                                               -- "Max_dt"
  ---------------------------------------------------------------------------
  begin
  ---------------------------------------------------------------------------
  -- Put the earliest time value of all given time vectors into "old_t"
  ---------------------------------------------------------------------------
    old_t := Twfm_1(Twfm_1'left);
    if (Twfm_2(Twfm_2'left) < old_t) then old_t := Twfm_2(Twfm_2'left);
    end if;
    if (Twfm_3(Twfm_3'left) < old_t) then old_t := Twfm_3(Twfm_3'left);
    end if;
    if (Twfm_4(Twfm_4'left) < old_t) then old_t := Twfm_4(Twfm_4'left);
    end if;
  ---------------------------------------------------------------------------
  -- Put the latest time value of all given time vectors into "new_t"
  ---------------------------------------------------------------------------
    new_t := Twfm_1(Twfm_1'right);
    if (Twfm_2(Twfm_2'right) > new_t) then new_t := Twfm_2(Twfm_2'right);
    end if;
    if (Twfm_3(Twfm_3'right) > new_t) then new_t := Twfm_3(Twfm_3'right);
    end if;
    if (Twfm_4(Twfm_4'right) > new_t) then new_t := Twfm_4(Twfm_4'right);
    end if;
    new_t := new_t;
  ---------------------------------------------------------------------------
  -- Loop until last index is reached in each given time vector
  ---------------------------------------------------------------------------
  index := New_time'left;
  while (old_t < new_t) loop
    -------------------------------------------------------------------------
    -- Find which given time vector(s) have the lowest time value and
    -- advance their temporary indexes
    -------------------------------------------------------------------------
    if (Twfm_1(index_1) <= old_t) then new_index_1 := index_1 + 1;
    end if;
    if (Twfm_2(index_2) <= old_t) then new_index_2 := index_2 + 1;
    end if;
    if (Twfm_3(index_3) <= old_t) then new_index_3 := index_3 + 1;
    end if;
    if (Twfm_4(index_4) <= old_t) then new_index_4 := index_4 + 1;
    end if;
    -------------------------------------------------------------------------
    -- Find the lowest value at the new indexes in the given vector(s) and
    -- update indexes for next iteration
    -------------------------------------------------------------------------
    if (new_index_1 <= Twfm_1'right) then
      if (Twfm_1(new_index_1) < new_t) then new_t := Twfm_1(new_index_1);
      end if;
      index_1 := new_index_1;
    end if;
    if (new_index_2 <= Twfm_2'right) then
      if (Twfm_2(new_index_2) < new_t) then new_t := Twfm_2(new_index_2);
      end if;
      index_2 := new_index_2;
    end if;
    if (new_index_3 <= Twfm_3'right) then
      if (Twfm_3(new_index_3) < new_t) then new_t := Twfm_3(new_index_3);
      end if;
      index_3 := new_index_3;
    end if;
    if (new_index_4 <= Twfm_4'right) then
      if (Twfm_4(new_index_4) < new_t) then new_t := Twfm_4(new_index_4);
      end if;
      index_4 := new_index_4;
    end if;
    -------------------------------------------------------------------------
    -- Calculate how many additional points are needed between the given
    -- points to satisfy the "Max_dt" separation criteria.  Note: the extra
    -- logic is needed due to floating point inaccuracies.
    -------------------------------------------------------------------------
    extra_points := integer(ceil((new_t-old_t)/Max_dt));

    remainder := "mod"((new_t-old_t),Max_dt);
    if remainder < (min_dt * Max_dt) and
       remainder > 0.0 then extra_points := extra_points - 1;
    end if;
    -------------------------------------------------------------------------
    -- Calculate and write the values of points into the "New_time" vector
    -------------------------------------------------------------------------
    for x_index in 0 to (extra_points - 1) loop
      New_time(index) := old_t + (real(x_index) * (new_t-old_t)) / real(extra_points);
      index := index + 1;
    end loop; 
    -------------------------------------------------------------------------
    -- Update variables for next iteration
    -------------------------------------------------------------------------
    old_t   := new_t;

    new_t := Twfm_1(Twfm_1'right);
    if (Twfm_2(Twfm_2'right) > new_t) then new_t := Twfm_2(Twfm_2'right);
    end if;
    if (Twfm_3(Twfm_3'right) > new_t) then new_t := Twfm_3(Twfm_3'right);
    end if;
    if (Twfm_4(Twfm_4'right) > new_t) then new_t := Twfm_4(Twfm_4'right);
    end if;
    new_t := new_t;
  ---------------------------------------------------------------------------
  end loop; 
  ---------------------------------------------------------------------------
  -- Insert the largest value at the end of the given vector(s) into the
  -- last position of "New_time".  (The loop above stops at the next to
  -- the last point).
  ---------------------------------------------------------------------------
                                            -- This may look better than the
                                            -- next line, but doesn't seem to
--  New_time(New_time'right) := new_t;      -- work due to a possible bug.
  New_time(index) := new_t;
  ---------------------------------------------------------------------------
  return New_time;
  end function Common_time;
--===========================================================================
--===========================================================================
  function Common_wfm (New_t : in real_vector;
                       Vwfm  : in real_vector;
                       Twfm  : in real_vector) return real_vector is
  ---------------------------------------------------------------------------
  -- This function generates an interpolated vector based on the input vector
  -- "New_t" using the input vector pair "Vwfm" and "Twfm".
  ---------------------------------------------------------------------------
  variable New_v : real_vector(New_t'range) := (others => 1.0);
  ---------------------------------------------------------------------------
  begin
                                        -- This is the better notation
                                        -- but it doesn't work due to
--  for index in New_v'range loop       -- a bug in SystemVision
    for index in New_v'left to New_v'right loop
      New_v(index) := Lookup("Vt", New_t(index), Vwfm, Twfm);
    end loop; 

  return New_v;
  end function Common_wfm;
--===========================================================================
--===========================================================================
  function Coeff (Edge     : in string;
                  Vwfm_pu  : in real_vector;
                  Vwfm_pd  : in real_vector;
                  Twfm     : in real_vector;
                  Rfx_pu   : in real;
                  Rfx_pd   : in real;
                  Vfx_pu   : in real;
                  Vfx_pd   : in real;
                  Iiv_pu   : in real_vector;
                  Viv_pu   : in real_vector;
                  Iiv_pd   : in real_vector;
                  Viv_pd   : in real_vector;
                  V_pu_ref : in real;
                  V_pd_ref : in real;
                  C_comp   : in real) return real_vector is
  ---------------------------------------------------------------------------
  -- This function converts each Vt curve to a corresponding scaling
  -- coefficient curve that is used to scale the IV curves with respect
  -- to time.  The effects of C_comp on the waveforms are included in the
  -- scaling coefficients, so that the presence of C_comp in the output
  -- stage will not "load" the driver, i.e. C_comp in the output stage 
  -- will not derate the original waveforms in the Vt curves.
  -- 
  -- 12/05/03 (LG) : added C_comp in the list of parameters. The function doesn't
  --                 have to be in the visibility region of C_comp anymore.
  ---------------------------------------------------------------------------
--  variable Kout     : real_vector(Vwfm_pu'range);     -- This is the better notation
--  variable dVwfm_pu : real_vector(Vwfm_pu'range);     -- but it doesn't work due to
--  variable dVwfm_pd : real_vector(Vwfm_pd'range);     -- a bug in SystemVision

  variable Kout     : real_vector(Vwfm_pu'left to Vwfm_pu'right);
  variable dVwfm_pu : real_vector(Vwfm_pu'left to Vwfm_pu'right);
  variable dVwfm_pd : real_vector(Vwfm_pd'left to Vwfm_pd'right);

  variable I1   : real := 0.0;
  variable I2   : real := 0.0;
  variable I3   : real := 0.0;
  variable I4   : real := 0.0;
  variable Ifx1 : real := 0.0;
  variable Ifx2 : real := 0.0;
  variable num  : real := 0.0;
  variable den  : real := 1.0;
  ---------------------------------------------------------------------------
  begin
  ---------------------------------------------------------------------------
  -- Generate the derivative of each waveform
  ---------------------------------------------------------------------------
    for index in Vwfm_pu'range loop
    -------------------------------------------------------------------------
    -- Force the derivatives of the first and last points to zero
    -------------------------------------------------------------------------
      if (index = Vwfm_pu'left) then
        dVwfm_pu(index) := 0.0;
        dVwfm_pd(index) := 0.0;
      elsif (index = Vwfm_pu'right) then
        dVwfm_pu(index) := 0.0;
        dVwfm_pd(index) := 0.0;
      -----------------------------------------------------------------------
      -- Calculate the derivative of a point using both of its neighbors
      -----------------------------------------------------------------------
      else
        dVwfm_pu(index) := ((Vwfm_pu(index) - Vwfm_pu(index-1))/(Twfm(index) - Twfm(index-1)) +
                            (Vwfm_pu(index+1) - Vwfm_pu(index))/(Twfm(index+1) - Twfm(index)))/2.0;
        dVwfm_pd(index) := ((Vwfm_pd(index) - Vwfm_pd(index-1))/(Twfm(index) - Twfm(index-1)) +
                            (Vwfm_pd(index+1) - Vwfm_pd(index))/(Twfm(index+1) - Twfm(index)))/2.0;
      end if;
      -----------------------------------------------------------------------
      -- Calculate intermediate (current) variables
      -----------------------------------------------------------------------
      I1   :=        Lookup("IV", Vwfm_pd(index) - V_pd_ref, Iiv_pd, Viv_pd);
      I2   :=        Lookup("IV", Vwfm_pu(index) - V_pd_ref, Iiv_pd, Viv_pd);
      I3   := -1.0 * Lookup("IV", V_pu_ref - Vwfm_pu(index), Iiv_pu, Viv_pu);
      I4   := -1.0 * Lookup("IV", V_pu_ref - Vwfm_pd(index), Iiv_pu, Viv_pu);
      -----------------------------------------------------------------------
      -- Calculate intermediate (fixture) variables
      -----------------------------------------------------------------------
      Ifx1 := ((Vwfm_pu(index) - Vfx_pu) / Rfx_pu) + C_comp * dVwfm_pu(index);
      Ifx2 := ((Vfx_pd - Vwfm_pd(index)) / Rfx_pd) - C_comp * dVwfm_pd(index);
      -----------------------------------------------------------------------
      -- Set up the numerator of the equation depending on the direction of
      -- the transition, and set up denominator of the equation.
      -----------------------------------------------------------------------
      if (Edge = "K_pu_on") or (Edge = "K_pu_off") then
        num  := (Ifx1 * I1) + (Ifx2 * I2);
      elsif (Edge = "K_pd_on") or (Edge = "K_pd_off") then
        num  := (Ifx1 * I4) + (Ifx2 * I3);
      else
        num  := 0.0;
      end if;

      den  := (I1 * I3) - (I2 * I4);
      -----------------------------------------------------------------------
      -- This is the master equation that solves for the scaling coefficients
      -----------------------------------------------------------------------
      Kout(index) := num / den;
    -------------------------------------------------------------------------
    end loop;
    -------------------------------------------------------------------------
  return Kout;
  end function Coeff;
--===========================================================================
end package body IBIS_Kernel_functions;
--===========================================================================
--===========================================================================
--===========================================================================
--===========================================================================
-- Clamp element.
--
-- Features: this entity implements a clamp element to be used in
--           the IBIS buffer.
--
-- To be done: re-code in a more general way, especially concerning
--             the way to pass some key parameters from the
--             instantiating entity.
--             (As soon as I get a VHDL-AMS simulator implementing
--             the whole features of the language, in particular:
--             file I/O, shared variables, records, access types.)
--
--===========================================================================
library IEEE;
use IEEE.math_real.all;
use IEEE.std_logic_1164.all;
library IEEE_proposed;
use IEEE_proposed.electrical_systems.all;
use IEEE_proposed.energy_systems.all;
use work.IBIS_Kernel_functions.all;
--===========================================================================
entity IV_clamp is

   generic (I : real_vector;
            V : real_vector;
            direction : integer);   --current flow direction
   ------------------------------------------------------------------------
   port (terminal Plus_node  : electrical;
         terminal Minus_node : electrical);
--===========================================================================
begin
   assert ((direction = -1) or (direction = 1))
      report "Variable 'direction' is OUT OF RANGE!";
end entity IV_clamp;
--===========================================================================
architecture tabled_IV of IV_clamp is
   quantity voltage across current through Plus_node to Minus_node;

begin
   current   == real(direction) * Lookup("IV", voltage, I, V); 
end architecture tabled_IV;
--===========================================================================
--===========================================================================
--===========================================================================
--===========================================================================
-- Transistor element.
--
-- Features: this entity implements a transistor element to be used
--           in the IBIS buffer.
--
-- To be done: re-code in a more general way, especially concerning
--             the way to pass some key parameters from the
--             instantiating entity.
--             (As soon as I get a VHDL-AMS simulator implementing
--             the whole features of the language, in particular:
--             file I/O, shared variables, records, access types.)
--
--===========================================================================
library IEEE;
use IEEE.math_real.all;
use IEEE.std_logic_1164.all;
library IEEE_proposed;
use IEEE_proposed.electrical_systems.all;
use IEEE_proposed.energy_systems.all;

use work.IBIS_Kernel_functions.all;
--===========================================================================
entity IV_transistor is

   generic (I : real_vector;
            V : real_vector;
            direction : integer;
            Kxx_on_A  : real_vector;
            Kxx_off_A : real_vector;
            Kxx_on_B  : real_vector;
            Kxx_off_B : real_vector;
            Kxx_on_C  : real_vector;
            Kxx_off_C : real_vector;
            Common_Time : real_vector);

   ------------------------------------------------------------------------
   port (terminal Plus_node  : electrical;
         terminal Minus_node : electrical;
                 signal px_on  : std_logic;
                 signal px_off : std_logic;
                 signal ZoneABC : character range 'A' to 'C');
--               signal Event_time : real);  --I can create it locally, but as "shared-variable"
   ------------------------------------------------------------------------
begin
   assert ((direction = -1) or (direction = 1))
      report "Variable 'direction' is OUT OF RANGE!";
end entity IV_transistor;
--===========================================================================
architecture tabled_IV of IV_transistor is
   quantity voltage across current through Plus_node to Minus_node;
   --***  this two signals should  ***
   --*** become "shared-variables" ***
   quantity kxx : real := 0.0;   --To store the actual K-table coefficient
   signal Event_time : real := 0.0;
begin
   ------------------------------------------------
   -- Concurrent statemet(s)
   ------------------------------------------------
   Sense_event : process(px_on, px_off) is
   begin
      Event_time <= now;
   end process Sense_event;

   break on px_on;
   break on px_off;
   ------------------------------------------------
   -- Simultaneous statemet(s)
   ------------------------------------------------
   if (Event_time = 0.0) use     --Initialization
      Initial_conditions :
      if (px_on = '1') use
         case ZoneABC use
            when 'A' => kxx == Kxx_on_A(Kxx_on_A'right);   --That is, kxx=1 !!!
            when 'B' => kxx == Kxx_on_B(Kxx_on_B'right);   --That is, kxx=1 !!!
            when 'C' => kxx == Kxx_on_C(Kxx_on_C'right);   --That is, kxx=1 !!!
         end case;
      elsif (px_off = '1') use
         case ZoneABC use
            when 'A' => kxx == Kxx_off_A(Kxx_off_A'right); --That is, kxx=0 !!!
            when 'B' => kxx == Kxx_off_B(Kxx_off_B'right); --That is, kxx=0 !!!
            when 'C' => kxx == Kxx_off_C(Kxx_off_C'right); --That is, kxx=0 !!!
         end case;
      else
--          kxx == 0;    --This form crashes really bad the HDL compiler!!
            kxx == 0.0;
         end use Initial_conditions;
   else                          --Normal operation
         Normal_conditions :
      if (px_on  = '1') use
         case ZoneABC use
            when 'A' => kxx == Lookup("Vt", now - Event_time, Kxx_on_A, Common_Time);
            when 'B' => kxx == Lookup("Vt", now - Event_time, Kxx_on_B, Common_Time);
            when 'C' => kxx == Lookup("Vt", now - Event_time, Kxx_on_C, Common_Time);
         end case;
      elsif (px_off = '1') use 
         case ZoneABC use
            when 'A' => kxx == Lookup("Vt", now - Event_time, Kxx_off_A, Common_Time);
            when 'B' => kxx == Lookup("Vt", now - Event_time, Kxx_off_B, Common_Time);
            when 'C' => kxx == Lookup("Vt", now - Event_time, Kxx_off_C, Common_Time);
         end case;
      else
         case ZoneABC use
            when 'A' => kxx == Kxx_on_A(Kxx_on_A'left);     --That is, kxx=0 !!!
            when 'B' => kxx == Kxx_on_B(Kxx_on_B'left);     --That is, kxx=0 !!!
            when 'C' => kxx == Kxx_on_C(Kxx_on_C'left);     --That is, kxx=0 !!!
         end case;
      end use Normal_conditions;
   end use;
   current == real(direction) * kxx * Lookup("IV", voltage, I, V); 
end architecture tabled_IV;
--===========================================================================
--===========================================================================
--===========================================================================
--===========================================================================
-- Die-capacitance element.
--
-- Features: This entity can be set to act as a standard
-- linear capacitance or as a non-linear capacitance.
--
-- To be done: the non-linear behaviour hasn't been coded yet.
--
--===========================================================================
library IEEE;
use IEEE.math_real.all;
use IEEE.std_logic_1164.all;
library IEEE_proposed;
use IEEE_proposed.electrical_systems.all;
use IEEE_proposed.energy_systems.all;
use work.some_types.all;
--===========================================================================
entity Die_cap is

   generic (Which : Ccomp_type := C_comp;
            C     : real := 0.0);
   ------------------------------------------------------------------------
   port (terminal Plus_node  : electrical;
         terminal Minus_node : electrical;
         quantity V_nl : in voltage);   -- this is the driving voltage
                                        -- for the non-linear operation
end entity Die_cap;
--===========================================================================
architecture C_or_C_NL of Die_cap is
   quantity v across i through Plus_node to Minus_node;
begin
   die_capacitance_chooser :
   if ((Which = Ccomp_type'(C_comp)) or (Which = C_comp4)) use
      i == C * v'dot;
   else
--    assert (false) report "This feature (non-linear capacitors) isn't implemented yet!";
      v == 1.0e9 * i;  --open circuit, for the moment,
                       --to be filled with the right behaviour
   end use die_capacitance_chooser;
end architecture C_or_C_NL;
--===========================================================================
--===========================================================================
--===========================================================================
--===========================================================================
-- Outer level of the IBIS element.
--
-- Features: this entity instantiates the transistors, the
--           clamps, the die-capacitance. It also provides
--           the logic interpreting the signals governing
--           the buffer.
--
-- To be done: 1) re-code in a more general way.
--                (As soon as I get a VHDL-AMS simulator implementing
--                the whole features of the language, in particular:
--                file I/O, shared variables, records, access types.)
--             2) Enhance the logic that chooses among the K-tables,
--                in order to account also for the current sourced
--                (i.e., for the loading conditions).
--
--===========================================================================
library IEEE;
use IEEE.math_real.all;
use IEEE.std_logic_1164.all;
library IEEE_proposed;
use IEEE_proposed.electrical_systems.all;
use IEEE_proposed.energy_systems.all;
use work.some_types.all;
use work.IBIS_Kernel_functions.all;
--===========================================================================
entity IBIS_IO is

   generic (IBIS_file    : string := "IBIS filename ?";
            Model        : string := "[Model] ?";
            Corner       : corner_type := Typ;
            Which_C_comp : Ccomp_type  := C_comp;

            Delta_t    : real := 200.0e-12);      -- This parameter
            -- determines what the maximum time delta will be between the
            -- points of the Vt curves and scaling coefficient curves
            -- after preprocessing the input data.
   ------------------------------------------------------------------------
   port (signal   In_D   : in   std_logic;
         signal   En_D   : in   std_logic;
         signal   Rcv_D  : out  std_logic;
   
         terminal IO     :      electrical;
         terminal PC_ref :      electrical;
         terminal PU_ref :      electrical;
         terminal PD_ref :      electrical;
         terminal GC_ref :      electrical);

end entity IBIS_IO;
--===========================================================================
architecture IO_buffer of IBIS_IO is

   signal    pu_on       : std_logic := '0';
   signal    pu_off      : std_logic := '0';
   signal    pd_on       : std_logic := '0';
   signal    pd_off      : std_logic := '0';

   signal    State_D     : std_logic := 'U';

   signal    In_time     : real := 0.0;
   signal    En_time     : real := 0.0;
   signal    Event_time  : real := 0.0;

   signal    Zone_ABC    : character range 'A' to 'C';

   quantity  V_pad across IO;

--***************************************************************************
--***************************************************************************
--***************************************************************************
-- The objects between here and the next asterisk-lines
-- should be removed.
-- They should be substituted by a record which has to be
-- declared "shared" (see Ashenden pag.41, about where it
-- is possible to declare a variable).
-- (An access-type to a record would be even better!)
-- The record should be initialized through a function
-- which takes as parameters: 'IBIS_file', 'Model' and
-- 'Corner' (and maybe also 'Which_C_comp'). The
-- function/procedure will perform the FILE I/O commands,
-- and return all these data.
------------------------------------------------------------------------
      constant C_comp :real := 4.55e-12;        -- Default C_comp value and
      constant k_C_comp_pc :real := 0.25;       -- splitting coefficients
      constant k_C_comp_pu :real := 0.25;
      constant k_C_comp_pd :real := 0.25;
      constant k_C_comp_gc :real := 0.25;
      ------------------------------------------------------------------
      -- [Pullup Reference] and [Pulldown Reference] values
      ------------------------------------------------------------------
      constant V_pu_ref :real := 5.0;
      constant V_pd_ref :real := 0.0;
      ------------------------------------------------------------------
      -- Vectors of the IV curve tables
      ------------------------------------------------------------------
      constant I_pc :real_vector := (
      7.05275039E+0,
      6.96967831E+0,
      6.88663128E+0,
      6.80359060E+0,
      6.72054991E+0,
      6.63750922E+0,
      6.55448662E+0,
      6.38847236E+0,
      6.30546524E+0,
      6.22245811E+0,
      6.13947346E+0,
      6.05650805E+0,
      5.97354265E+0,
      5.89057725E+0,
      5.80761184E+0,
      5.72467222E+0,
      5.64175468E+0,
      5.55883714E+0,
      5.47591960E+0,
      5.39300206E+0,
      5.31011439E+0,
      5.22725232E+0,
      5.14439024E+0,
      5.06152816E+0,
      4.97866608E+0,
      4.89583904E+0,
      4.81304200E+0,
      4.73024497E+0,
      4.64744793E+0,
      4.56465089E+0,
      4.48189551E+0,
      4.39917580E+0,
      4.31645609E+0,
      4.23373638E+0,
      4.15101667E+0,
      4.06834729E+0,
      3.98572101E+0,
      3.90309474E+0,
      3.82046846E+0,
      3.73784219E+0,
      3.65527793E+0,
      3.57276680E+0,
      3.49025566E+0,
      3.40774452E+0,
      3.32523338E+0,
      3.24280053E+0,
      3.16043473E+0,
      3.07806892E+0,
      2.99570312E+0,
      2.91333732E+0,
      2.83107338E+0,
      2.74889668E+0,
      2.66671999E+0,
      2.58454329E+0,
      2.50236659E+0,
      2.42032775E+0,
      2.33840698E+0,
      2.25648621E+0,
      2.17456544E+0,
      2.09264466E+0,
      2.01092444E+0,
      1.92937599E+0,
      1.84782753E+0,
      1.76627908E+0,
      1.68473062E+0,
      1.60348610E+0,
      1.52250189E+0,
      1.44151767E+0,
      1.36053346E+0,
      1.27954925E+0,
      1.19909898E+0,
      1.03911308E+0,
    959.12013000E-3,
    879.12718000E-3,
    800.29573000E-3,
    722.45907000E-3,
    644.62241000E-3,
    566.78575000E-3,
    488.94909000E-3,
    415.40080000E-3,
    345.52536000E-3,
    275.64992000E-3,
    205.77448000E-3,
    135.89904000E-3,
     76.93086500E-3,
     34.07280400E-3,
      8.83732430E-3,
      7.05636240E-3,
      5.27540060E-3,
      3.49443880E-3,
      1.71347690E-3,
      1.34986900E-6,
      1.07782600E-6,
    805.78297000E-9,
    533.73996000E-9,
    261.69695000E-9,
   168.32060000E-12,
    75.82463200E-12,
     3.79123160E-12,
      0.00000000E+0);
      constant V_pc :real_vector := (
     -5.00000000E+0,
     -4.95000000E+0,
     -4.90000000E+0,
     -4.85000000E+0,
     -4.80000000E+0,
     -4.75000000E+0,
     -4.70000000E+0,
     -4.60000000E+0,
     -4.55000000E+0,
     -4.50000000E+0,
     -4.45000000E+0,
     -4.40000000E+0,
     -4.35000000E+0,
     -4.30000000E+0,
     -4.25000000E+0,
     -4.20000000E+0,
     -4.15000000E+0,
     -4.10000000E+0,
     -4.05000000E+0,
     -4.00000000E+0,
     -3.95000000E+0,
     -3.90000000E+0,
     -3.85000000E+0,
     -3.80000000E+0,
     -3.75000000E+0,
     -3.70000000E+0,
     -3.65000000E+0,
     -3.60000000E+0,
     -3.55000000E+0,
     -3.50000000E+0,
     -3.45000000E+0,
     -3.40000000E+0,
     -3.35000000E+0,
     -3.30000000E+0,
     -3.25000000E+0,
     -3.20000000E+0,
     -3.15000000E+0,
     -3.10000000E+0,
     -3.05000000E+0,
     -3.00000000E+0,
     -2.95000000E+0,
     -2.90000000E+0,
     -2.85000000E+0,
     -2.80000000E+0,
     -2.75000000E+0,
     -2.70000000E+0,
     -2.65000000E+0,
     -2.60000000E+0,
     -2.55000000E+0,
     -2.50000000E+0,
     -2.45000000E+0,
     -2.40000000E+0,
     -2.35000000E+0,
     -2.30000000E+0,
     -2.25000000E+0,
     -2.20000000E+0,
     -2.15000000E+0,
     -2.10000000E+0,
     -2.05000000E+0,
     -2.00000000E+0,
     -1.95000000E+0,
     -1.90000000E+0,
     -1.85000000E+0,
     -1.80000000E+0,
     -1.75000000E+0,
     -1.70000000E+0,
     -1.65000000E+0,
     -1.60000000E+0,
     -1.55000000E+0,
     -1.50000000E+0,
     -1.45000000E+0,
     -1.35000000E+0,
     -1.30000000E+0,
     -1.25000000E+0,
     -1.20000000E+0,
     -1.15000000E+0,
     -1.10000000E+0,
     -1.05000000E+0,
     -1.00000000E+0,
   -950.00000000E-3,
   -900.00000000E-3,
   -850.00000000E-3,
   -800.00000000E-3,
   -750.00000000E-3,
   -700.00000000E-3,
   -650.00000000E-3,
   -600.00000000E-3,
   -550.00000000E-3,
   -500.00000000E-3,
   -450.00000000E-3,
   -400.00000000E-3,
   -350.00000000E-3,
   -300.00000000E-3,
   -250.00000000E-3,
   -200.00000000E-3,
   -150.00000000E-3,
   -100.00000000E-3,
      0.00000000E+0,
      4.75000000E+0,
     10.00000000E+0);
      constant I_pu :real_vector := (
    149.68000000E-6,
    193.95000000E-6,
    203.16000000E-6,
    206.30000000E-6,
    220.27000000E-6,
    249.40000000E-6,
    265.06000000E-6,
    275.79000000E-6,
    316.13000000E-6,
    341.60000000E-6,
    360.03000000E-6,
    382.39000000E-6,
    418.23000000E-6,
    464.44000000E-6,
    479.85000000E-6,
    544.87000000E-6,
    590.50000000E-6,
    620.69000000E-6,
    693.70000000E-6,
    766.71000000E-6,
    820.25000000E-6,
    956.50000000E-6,
      1.02462000E-3,
      1.09274000E-3,
      1.21526000E-3,
      1.55345000E-3,
      1.72255000E-3,
      1.89165000E-3,
      2.44004000E-3,
      4.18657000E-3,
      5.05983000E-3,
      5.93310000E-3,
      8.08750700E-3,
     11.45421400E-3,
     14.92706970E-3,
     13.05428240E-3,
     12.11788820E-3,
     11.18149410E-3,
     10.22482513E-3,
      7.30303852E-3,
      5.84214516E-3,
      2.92123793E-3,
     44.94540518E-6,
     -1.39320083E-3,
     -4.26532944E-3,
     -6.92618876E-3,
     -8.25661838E-3,
     -9.58704809E-3,
    -10.91307700E-3,
    -13.34623197E-3,
    -14.56280996E-3,
    -15.77938794E-3,
    -16.99166893E-3,
    -19.20253295E-3,
    -20.30796597E-3,
    -21.41339798E-3,
    -22.51463599E-3,
    -24.50850196E-3,
    -25.50543494E-3,
    -26.50236893E-3,
    -27.49520792E-3,
    -29.27724994E-3,
    -30.16827095E-3,
    -31.05929196E-3,
    -31.94631697E-3,
    -33.52158994E-3,
    -34.30922693E-3,
    -35.09686391E-3,
    -35.88059890E-3,
    -37.25403792E-3,
    -37.94075793E-3,
    -38.62747694E-3,
    -39.31038895E-3,
    -40.48681092E-3,
    -41.07502091E-3,
    -42.24772588E-3,
    -43.23182790E-3,
    -43.72387891E-3,
    -44.70435294E-3,
    -45.50071591E-3,
    -45.89889689E-3,
    -46.69171786E-3,
    -47.30480488E-3,
    -47.61134889E-3,
    -48.22097792E-3,
    -48.65513489E-3,
    -48.87221387E-3,
    -49.30299484E-3,
    -49.56245986E-3,
    -49.69219287E-3,
    -49.94948390E-3,
    -50.16989985E-3,
    -52.50527174E-3,
    -53.45967000E-3,
    -54.71289000E-3,
    -54.78684000E-3,
    -55.67534000E-3,
    -56.93886000E-3,
    -58.58253000E-3,
    -59.70595000E-3);
      constant V_pu :real_vector := (
     -5.00000000E+0,
     -4.00000000E+0,
     -3.85000000E+0,
     -3.80000000E+0,
     -3.60000000E+0,
     -3.25000000E+0,
     -3.10000000E+0,
     -3.00000000E+0,
     -2.70000000E+0,
     -2.55000000E+0,
     -2.45000000E+0,
     -2.35000000E+0,
     -2.20000000E+0,
     -2.05000000E+0,
     -2.00000000E+0,
     -1.85000000E+0,
     -1.75000000E+0,
     -1.70000000E+0,
     -1.60000000E+0,
     -1.50000000E+0,
     -1.45000000E+0,
     -1.35000000E+0,
     -1.30000000E+0,
     -1.25000000E+0,
     -1.20000000E+0,
     -1.10000000E+0,
     -1.05000000E+0,
     -1.00000000E+0,
   -950.00000000E-3,
   -850.00000000E-3,
   -800.00000000E-3,
   -750.00000000E-3,
   -700.00000000E-3,
   -650.00000000E-3,
   -600.00000000E-3,
   -500.00000000E-3,
   -450.00000000E-3,
   -400.00000000E-3,
   -350.00000000E-3,
   -250.00000000E-3,
   -200.00000000E-3,
   -100.00000000E-3,
      0.00000000E+0,
     50.00000000E-3,
    150.00000000E-3,
    250.00000000E-3,
    300.00000000E-3,
    350.00000000E-3,
    400.00000000E-3,
    500.00000000E-3,
    550.00000000E-3,
    600.00000000E-3,
    650.00000000E-3,
    750.00000000E-3,
    800.00000000E-3,
    850.00000000E-3,
    900.00000000E-3,
      1.00000000E+0,
      1.05000000E+0,
      1.10000000E+0,
      1.15000000E+0,
      1.25000000E+0,
      1.30000000E+0,
      1.35000000E+0,
      1.40000000E+0,
      1.50000000E+0,
      1.55000000E+0,
      1.60000000E+0,
      1.65000000E+0,
      1.75000000E+0,
      1.80000000E+0,
      1.85000000E+0,
      1.90000000E+0,
      2.00000000E+0,
      2.05000000E+0,
      2.15000000E+0,
      2.25000000E+0,
      2.30000000E+0,
      2.40000000E+0,
      2.50000000E+0,
      2.55000000E+0,
      2.65000000E+0,
      2.75000000E+0,
      2.80000000E+0,
      2.90000000E+0,
      3.00000000E+0,
      3.05000000E+0,
      3.15000000E+0,
      3.25000000E+0,
      3.30000000E+0,
      3.40000000E+0,
      3.55000000E+0,
      5.15000000E+0,
      5.80000000E+0,
      6.65000000E+0,
      6.70000000E+0,
      7.30000000E+0,
      8.15000000E+0,
      9.25000000E+0,
     10.00000000E+0);
      constant I_pd :real_vector := (
   -206.98000000E-6,
   -233.88000000E-6,
   -243.52000000E-6,
   -250.06000000E-6,
   -268.66000000E-6,
   -281.52000000E-6,
   -290.29000000E-6,
   -315.74000000E-6,
   -333.80000000E-6,
   -346.15000000E-6,
   -368.07000000E-6,
   -383.09000000E-6,
   -391.59000000E-6,
   -410.28000000E-6,
   -428.95000000E-6,
   -439.70000000E-6,
   -475.48000000E-6,
   -501.41000000E-6,
   -532.92000000E-6,
   -583.43000000E-6,
   -626.97000000E-6,
   -648.75000000E-6,
   -670.53000000E-6,
   -698.02000000E-6,
   -762.80000000E-6,
   -795.21000000E-6,
   -827.60000000E-6,
   -870.65000000E-6,
   -975.01000000E-6,
     -1.02719000E-3,
     -1.07936000E-3,
     -1.15646000E-3,
     -1.35337000E-3,
     -1.45182000E-3,
     -1.55027000E-3,
     -1.73037000E-3,
     -2.23042000E-3,
     -2.48044000E-3,
     -2.73046000E-3,
     -3.58381000E-3,
     -6.32400000E-3,
     -7.69410000E-3,
     -9.06419300E-3,
    -12.36007100E-3,
    -17.15828500E-3,
    -21.36801170E-3,
    -18.54070610E-3,
    -17.12705280E-3,
    -15.71340054E-3,
    -14.27608395E-3,
    -10.22449400E-3,
     -8.19869893E-3,
     -4.14679843E-3,
    -79.15884987E-6,
      1.95466091E-3,
      3.98848068E-3,
      6.01362436E-3,
      9.63237697E-3,
     11.44175307E-3,
     13.25113007E-3,
     15.05137907E-3,
     18.19795106E-3,
     19.77123605E-3,
     21.34452205E-3,
     22.90920804E-3,
     25.61083805E-3,
     26.96165305E-3,
     28.31246805E-3,
     29.65518505E-3,
     31.93781604E-3,
     33.07913203E-3,
     34.22044703E-3,
     35.35414002E-3,
     37.24237802E-3,
     38.18649603E-3,
     39.13061503E-3,
     40.06756103E-3,
     41.58466002E-3,
     42.34321001E-3,
     43.10175901E-3,
     43.85355900E-3,
     45.02143300E-3,
     45.60537000E-3,
     46.18930701E-3,
     46.76689201E-3,
     47.60613500E-3,
     48.02575599E-3,
     48.44537798E-3,
     48.85901998E-3,
     49.38894398E-3,
     49.65390598E-3,
     49.91886798E-3,
     50.17767299E-3,
     50.38906397E-3,
     50.49475997E-3,
     50.70278095E-3,
     50.75837996E-3,
     52.04000000E-3,
     52.09584000E-3,
     53.43931000E-3);
      constant V_pd :real_vector := (
     -5.00000000E+0,
     -4.50000000E+0,
     -4.35000000E+0,
     -4.25000000E+0,
     -4.00000000E+0,
     -3.85000000E+0,
     -3.75000000E+0,
     -3.50000000E+0,
     -3.35000000E+0,
     -3.25000000E+0,
     -3.10000000E+0,
     -3.00000000E+0,
     -2.95000000E+0,
     -2.85000000E+0,
     -2.75000000E+0,
     -2.70000000E+0,
     -2.55000000E+0,
     -2.45000000E+0,
     -2.35000000E+0,
     -2.20000000E+0,
     -2.10000000E+0,
     -2.05000000E+0,
     -2.00000000E+0,
     -1.95000000E+0,
     -1.85000000E+0,
     -1.80000000E+0,
     -1.75000000E+0,
     -1.70000000E+0,
     -1.60000000E+0,
     -1.55000000E+0,
     -1.50000000E+0,
     -1.45000000E+0,
     -1.35000000E+0,
     -1.30000000E+0,
     -1.25000000E+0,
     -1.20000000E+0,
     -1.10000000E+0,
     -1.05000000E+0,
     -1.00000000E+0,
   -950.00000000E-3,
   -850.00000000E-3,
   -800.00000000E-3,
   -750.00000000E-3,
   -700.00000000E-3,
   -650.00000000E-3,
   -600.00000000E-3,
   -500.00000000E-3,
   -450.00000000E-3,
   -400.00000000E-3,
   -350.00000000E-3,
   -250.00000000E-3,
   -200.00000000E-3,
   -100.00000000E-3,
      0.00000000E+0,
     50.00000000E-3,
    100.00000000E-3,
    150.00000000E-3,
    250.00000000E-3,
    300.00000000E-3,
    350.00000000E-3,
    400.00000000E-3,
    500.00000000E-3,
    550.00000000E-3,
    600.00000000E-3,
    650.00000000E-3,
    750.00000000E-3,
    800.00000000E-3,
    850.00000000E-3,
    900.00000000E-3,
      1.00000000E+0,
      1.05000000E+0,
      1.10000000E+0,
      1.15000000E+0,
      1.25000000E+0,
      1.30000000E+0,
      1.35000000E+0,
      1.40000000E+0,
      1.50000000E+0,
      1.55000000E+0,
      1.60000000E+0,
      1.65000000E+0,
      1.75000000E+0,
      1.80000000E+0,
      1.85000000E+0,
      1.90000000E+0,
      2.00000000E+0,
      2.05000000E+0,
      2.10000000E+0,
      2.15000000E+0,
      2.25000000E+0,
      2.30000000E+0,
      2.35000000E+0,
      2.40000000E+0,
      2.50000000E+0,
      2.55000000E+0,
      2.65000000E+0,
      2.80000000E+0,
      6.25000000E+0,
      6.40000000E+0,
     10.00000000E+0);
      constant I_gc :real_vector := (
     -4.02664322E+0,
     -3.97914877E+0,
     -3.93169315E+0,
     -3.88424134E+0,
     -3.83678953E+0,
     -3.78933772E+0,
     -3.74189644E+0,
     -3.69446417E+0,
     -3.64703190E+0,
     -3.59959964E+0,
     -3.55216737E+0,
     -3.50474796E+0,
     -3.45733958E+0,
     -3.40993119E+0,
     -3.36252281E+0,
     -3.31511442E+0,
     -3.26772081E+0,
     -3.22033985E+0,
     -3.17295889E+0,
     -3.12557793E+0,
     -3.07819697E+0,
     -3.03083312E+0,
     -2.98348392E+0,
     -2.93613472E+0,
     -2.88878552E+0,
     -2.84143632E+0,
     -2.79410720E+0,
     -2.74679528E+0,
     -2.69948336E+0,
     -2.65217144E+0,
     -2.60485952E+0,
     -2.55757146E+0,
     -2.51030385E+0,
     -2.46303623E+0,
     -2.41576862E+0,
     -2.36850100E+0,
     -2.32126225E+0,
     -2.27404821E+0,
     -2.22683417E+0,
     -2.17962013E+0,
     -2.13240609E+0,
     -2.08522761E+0,
     -2.03807959E+0,
     -1.99093156E+0,
     -1.94378354E+0,
     -1.89663552E+0,
     -1.84953241E+0,
     -1.75540315E+0,
     -1.70833852E+0,
     -1.66127389E+0,
     -1.61426772E+0,
     -1.56731163E+0,
     -1.52035554E+0,
     -1.47339945E+0,
     -1.42644336E+0,
     -1.37956647E+0,
     -1.33275740E+0,
     -1.28594834E+0,
     -1.23913927E+0,
     -1.19233020E+0,
     -1.14563646E+0,
     -1.09904149E+0,
     -1.05244652E+0,
     -1.00585154E+0,
   -959.25657000E-3,
   -912.83663000E-3,
   -866.56660000E-3,
   -820.29657000E-3,
   -774.02654000E-3,
   -727.75651000E-3,
   -681.79472000E-3,
   -636.09692000E-3,
   -590.39912000E-3,
   -544.70132000E-3,
   -499.00352000E-3,
   -453.97946000E-3,
   -409.53244000E-3,
   -365.08541000E-3,
   -320.63839000E-3,
   -276.19137000E-3,
   -234.26573000E-3,
   -194.49958000E-3,
   -154.73344000E-3,
   -114.96729000E-3,
    -75.20114600E-3,
    -41.92421200E-3,
    -18.13589300E-3,
     -4.54404430E-3,
     -2.71253890E-3,
     -1.79678620E-3,
   -881.03346000E-6,
   -675.04841000E-9,
   -402.99581000E-9,
   -266.96951000E-9,
   -130.94321000E-9,
  -174.30155000E-12,
  -129.13024000E-12,
    -6.45651200E-12,
      0.00000000E+0,
      0.00000000E+0);
      constant V_gc :real_vector := (
     -5.00000000E+0,
     -4.95000000E+0,
     -4.90000000E+0,
     -4.85000000E+0,
     -4.80000000E+0,
     -4.75000000E+0,
     -4.70000000E+0,
     -4.65000000E+0,
     -4.60000000E+0,
     -4.55000000E+0,
     -4.50000000E+0,
     -4.45000000E+0,
     -4.40000000E+0,
     -4.35000000E+0,
     -4.30000000E+0,
     -4.25000000E+0,
     -4.20000000E+0,
     -4.15000000E+0,
     -4.10000000E+0,
     -4.05000000E+0,
     -4.00000000E+0,
     -3.95000000E+0,
     -3.90000000E+0,
     -3.85000000E+0,
     -3.80000000E+0,
     -3.75000000E+0,
     -3.70000000E+0,
     -3.65000000E+0,
     -3.60000000E+0,
     -3.55000000E+0,
     -3.50000000E+0,
     -3.45000000E+0,
     -3.40000000E+0,
     -3.35000000E+0,
     -3.30000000E+0,
     -3.25000000E+0,
     -3.20000000E+0,
     -3.15000000E+0,
     -3.10000000E+0,
     -3.05000000E+0,
     -3.00000000E+0,
     -2.95000000E+0,
     -2.90000000E+0,
     -2.85000000E+0,
     -2.80000000E+0,
     -2.75000000E+0,
     -2.70000000E+0,
     -2.60000000E+0,
     -2.55000000E+0,
     -2.50000000E+0,
     -2.45000000E+0,
     -2.40000000E+0,
     -2.35000000E+0,
     -2.30000000E+0,
     -2.25000000E+0,
     -2.20000000E+0,
     -2.15000000E+0,
     -2.10000000E+0,
     -2.05000000E+0,
     -2.00000000E+0,
     -1.95000000E+0,
     -1.90000000E+0,
     -1.85000000E+0,
     -1.80000000E+0,
     -1.75000000E+0,
     -1.70000000E+0,
     -1.65000000E+0,
     -1.60000000E+0,
     -1.55000000E+0,
     -1.50000000E+0,
     -1.45000000E+0,
     -1.40000000E+0,
     -1.35000000E+0,
     -1.30000000E+0,
     -1.25000000E+0,
     -1.20000000E+0,
     -1.15000000E+0,
     -1.10000000E+0,
     -1.05000000E+0,
     -1.00000000E+0,
   -950.00000000E-3,
   -900.00000000E-3,
   -850.00000000E-3,
   -800.00000000E-3,
   -750.00000000E-3,
   -700.00000000E-3,
   -650.00000000E-3,
   -600.00000000E-3,
   -500.00000000E-3,
   -450.00000000E-3,
   -400.00000000E-3,
   -350.00000000E-3,
   -250.00000000E-3,
   -200.00000000E-3,
   -150.00000000E-3,
   -100.00000000E-3,
      0.00000000E+0,
      4.75000000E+0,
      5.00000000E+0,
     10.00000000E+0);
      ------------------------------------------------------------------
      -- Vectors of the Vt curve tables
      ------------------------------------------------------------------
      constant V_rise_0third  :real_vector := (
      1.30460912E-3,
      3.18808325E-3,
      3.47637375E-3,
      2.05355478E-3,
      1.27575273E-3,
     -4.18472999E-3,
    -11.41712818E-3,
    -17.43714395E-3,
    -29.87065181E-3,
    -36.90640838E-3,
    -45.50044887E-3,
    -50.62619659E-3,
    -64.31969783E-3,
    -78.62763791E-3,
    -43.27976297E-3,
    -25.68760394E-3,
    -19.61935623E-3,
    -18.38371316E-3,
    -18.01223578E-3,
    -16.61659038E-3,
    -15.99425893E-3,
    -15.51140689E-3,
     -7.71899624E-3,
     -5.60792411E-3,
     -4.35857753E-3,
     11.06036475E-3,
     19.87690034E-3,
     43.16189640E-3,
     58.54647554E-3,
     90.45194097E-3,
     95.62125683E-3,
    116.01347565E-3,
    155.69088006E-3,
    181.77034473E-3,
    192.79780632E-3,
    223.67142500E-3,
    278.39644551E-3,
    288.25393901E-3,
    306.29456365E-3,
    389.71566536E-3,
    404.06414066E-3,
    511.30551554E-3,
    522.08524692E-3,
    634.53900914E-3,
    667.64670654E-3,
    671.48992233E-3,
    830.69822816E-3,
    851.85377778E-3,
      1.00671082E+0,
      1.01066452E+0,
      1.12561645E+0,
      1.15138078E+0,
      1.16803869E+0,
      1.27246334E+0,
      1.30317362E+0,
      1.33229315E+0,
      1.37644795E+0,
      1.46186105E+0,
      1.53774419E+0,
      1.54736084E+0,
      1.63720570E+0,
      1.68821751E+0,
      1.72472582E+0,
      1.77126726E+0,
      1.77441225E+0,
      1.80802431E+0,
      1.84903753E+0,
      1.88741323E+0,
      1.91721427E+0,
      1.92212876E+0,
      1.98856625E+0,
      2.01902972E+0,
      2.03681995E+0,
      2.04144882E+0,
      2.08684422E+0,
      2.11993256E+0,
      2.12768729E+0,
      2.15147937E+0,
      2.16359129E+0,
      2.18011116E+0,
      2.20514947E+0,
      2.20918690E+0,
      2.21951766E+0,
      2.22706672E+0,
      2.26188946E+0,
      2.26221953E+0,
      2.26791871E+0,
      2.28779742E+0,
      2.29268097E+0,
      2.30412215E+0,
      2.31385396E+0,
      2.31626806E+0,
      2.32426782E+0,
      2.32498732E+0,
      2.32633456E+0,
      2.33091408E+0,
      2.33362647E+0,
      2.33454977E+0,
      2.33667489E+0,
      2.33820238E+0);
      constant T_rise_0third  :real_vector := (
      0.00000000E+0,
   293.00000000E-12,
   362.00000000E-12,
   416.00000000E-12,
   433.00000000E-12,
   514.00000000E-12,
   596.00000000E-12,
   654.00000000E-12,
   744.00000000E-12,
   787.00000000E-12,
   837.00000000E-12,
   864.00000000E-12,
   925.00000000E-12,
   994.00000000E-12,
      1.06800000E-9,
      1.13600000E-9,
      1.22700000E-9,
      1.29200000E-9,
      1.30900000E-9,
      1.37200000E-9,
      1.38300000E-9,
      1.39000000E-9,
      1.45200000E-9,
      1.46300000E-9,
      1.46900000E-9,
      1.52600000E-9,
      1.55100000E-9,
      1.60500000E-9,
      1.63500000E-9,
      1.68900000E-9,
      1.69700000E-9,
      1.72700000E-9,
      1.78000000E-9,
      1.81200000E-9,
      1.82500000E-9,
      1.86000000E-9,
      1.91800000E-9,
      1.92800000E-9,
      1.94600000E-9,
      2.02500000E-9,
      2.03800000E-9,
      2.13100000E-9,
      2.14000000E-9,
      2.23100000E-9,
      2.25700000E-9,
      2.26000000E-9,
      2.38200000E-9,
      2.39800000E-9,
      2.51500000E-9,
      2.51800000E-9,
      2.60600000E-9,
      2.62600000E-9,
      2.63900000E-9,
      2.72200000E-9,
      2.74700000E-9,
      2.77100000E-9,
      2.80800000E-9,
      2.88200000E-9,
      2.95100000E-9,
      2.96000000E-9,
      3.04800000E-9,
      3.10300000E-9,
      3.14500000E-9,
      3.20200000E-9,
      3.20600000E-9,
      3.25000000E-9,
      3.30700000E-9,
      3.36400000E-9,
      3.41100000E-9,
      3.41900000E-9,
      3.53500000E-9,
      3.59400000E-9,
      3.63100000E-9,
      3.64100000E-9,
      3.74900000E-9,
      3.84200000E-9,
      3.86600000E-9,
      3.94600000E-9,
      3.99100000E-9,
      4.05800000E-9,
      4.17500000E-9,
      4.19600000E-9,
      4.25300000E-9,
      4.29800000E-9,
      4.55700000E-9,
      4.56000000E-9,
      4.61400000E-9,
      4.84500000E-9,
      4.91600000E-9,
      5.11800000E-9,
      5.35300000E-9,
      5.42600000E-9,
      5.74300000E-9,
      5.78000000E-9,
      5.85500000E-9,
      6.19400000E-9,
      6.51500000E-9,
      6.66900000E-9,
      7.25000000E-9,
      9.00104318E-9);
-----------------------------------------------------------------------------
      constant V_fall_0third :real_vector := (
      2.33820238E+0,
      2.33687034E+0,
      2.33776776E+0,
      2.34023217E+0,
      2.34335857E+0,
      2.34627314E+0,
      2.35070222E+0,
      2.35149705E+0,
      2.35530855E+0,
      2.35584795E+0,
      2.35659864E+0,
      2.35468279E+0,
      2.34953639E+0,
      2.34383160E+0,
      2.34207793E+0,
      2.34171324E+0,
      2.33060532E+0,
      2.32323928E+0,
      2.31742261E+0,
      2.29960977E+0,
      2.29872682E+0,
      2.29231350E+0,
      2.28643361E+0,
      2.27125656E+0,
      2.24843731E+0,
      2.23840621E+0,
      2.23079200E+0,
      2.19998544E+0,
      2.13558344E+0,
      2.12814156E+0,
      2.05922782E+0,
      1.98879828E+0,
      1.96449335E+0,
      1.96095373E+0,
      1.88588574E+0,
      1.86177409E+0,
      1.82413232E+0,
      1.81132436E+0,
      1.73772916E+0,
      1.65394388E+0,
      1.61386886E+0,
      1.49290718E+0,
      1.48841878E+0,
      1.36744293E+0,
      1.32288455E+0,
      1.23453623E+0,
      1.19087541E+0,
      1.16056432E+0,
      1.10064310E+0,
      1.05430895E+0,
      1.04597158E+0,
    972.30841550E-3,
    916.64318497E-3,
    839.71803119E-3,
    780.55415519E-3,
    716.69270626E-3,
    655.83164371E-3,
    598.09298672E-3,
    549.45485493E-3,
    489.52071235E-3,
    454.64524507E-3,
    378.36925803E-3,
    369.22621448E-3,
    362.46871504E-3,
    290.14583514E-3,
    284.48546895E-3,
    227.67992731E-3,
    219.90794309E-3,
    188.21326790E-3,
    166.37006887E-3,
    165.15012704E-3,
    127.75585486E-3,
    121.00212262E-3,
    101.08628578E-3,
     89.75600850E-3,
     68.18682847E-3,
     67.72203049E-3,
     60.75317639E-3,
     49.85900845E-3,
     45.67311160E-3,
     39.15499895E-3,
     32.50600673E-3,
     27.92032050E-3,
     27.36652377E-3,
     23.34671728E-3,
     20.00894805E-3,
     17.64992720E-3,
     17.17111965E-3,
     15.72308962E-3,
     13.52833349E-3,
     10.29969482E-3,
      9.11950410E-3,
      6.93918062E-3,
      5.34188901E-3,
      2.03136359E-3,
      1.68631019E-3,
      1.30460912E-3);
      constant T_fall_0third :real_vector := (
      0.00000000E+0,
   253.00000000E-12,
   312.00000000E-12,
   377.00000000E-12,
   428.00000000E-12,
   466.00000000E-12,
   513.00000000E-12,
   521.00000000E-12,
   565.00000000E-12,
   574.00000000E-12,
   604.00000000E-12,
   638.00000000E-12,
   668.00000000E-12,
   688.00000000E-12,
   693.00000000E-12,
   694.00000000E-12,
   719.00000000E-12,
   732.00000000E-12,
   741.00000000E-12,
   764.00000000E-12,
   765.00000000E-12,
   772.00000000E-12,
   778.00000000E-12,
   792.00000000E-12,
   810.00000000E-12,
   817.00000000E-12,
   822.00000000E-12,
   840.00000000E-12,
   870.00000000E-12,
   873.00000000E-12,
   898.00000000E-12,
   920.00000000E-12,
   927.00000000E-12,
   928.00000000E-12,
   948.00000000E-12,
   954.00000000E-12,
   963.00000000E-12,
   966.00000000E-12,
   983.00000000E-12,
      1.00200000E-9,
      1.01100000E-9,
      1.03800000E-9,
      1.03900000E-9,
      1.06600000E-9,
      1.07600000E-9,
      1.09600000E-9,
      1.10600000E-9,
      1.11300000E-9,
      1.12700000E-9,
      1.13800000E-9,
      1.14000000E-9,
      1.15800000E-9,
      1.17200000E-9,
      1.19200000E-9,
      1.20800000E-9,
      1.22600000E-9,
      1.24400000E-9,
      1.26200000E-9,
      1.27800000E-9,
      1.29900000E-9,
      1.31200000E-9,
      1.34300000E-9,
      1.34700000E-9,
      1.35000000E-9,
      1.38500000E-9,
      1.38800000E-9,
      1.42100000E-9,
      1.42600000E-9,
      1.44800000E-9,
      1.46500000E-9,
      1.46600000E-9,
      1.50000000E-9,
      1.50700000E-9,
      1.53000000E-9,
      1.54800000E-9,
      1.58800000E-9,
      1.58900000E-9,
      1.60500000E-9,
      1.63500000E-9,
      1.64900000E-9,
      1.68100000E-9,
      1.72800000E-9,
      1.77100000E-9,
      1.77700000E-9,
      1.82800000E-9,
      1.88500000E-9,
      1.93900000E-9,
      1.95200000E-9,
      1.99700000E-9,
      2.08800000E-9,
      2.31000000E-9,
      2.43200000E-9,
      2.73500000E-9,
      3.04200000E-9,
      4.48700000E-9,
      5.00400000E-9,
      9.00104318E-9);
-----------------------------------------------------------------------------
      constant V_fall_3third  :real_vector := (
      4.99907829E+0,
      4.99700156E+0,
      4.99690424E+0,
      4.99886112E+0,
      5.00069667E+0,
      5.01652115E+0,
      5.01799055E+0,
      5.02039060E+0,
      5.05255798E+0,
      5.05275062E+0,
      5.06401690E+0,
      5.07922504E+0,
      5.08355880E+0,
      5.08453391E+0,
      5.08462664E+0,
      5.08467249E+0,
      5.08621580E+0,
      5.08706948E+0,
      5.08715557E+0,
      5.08642829E+0,
      5.08487366E+0,
      5.08247348E+0,
      5.07924833E+0,
      5.07849917E+0,
      5.06802997E+0,
      5.02303553E+0,
      4.96407070E+0,
      4.89533955E+0,
      4.84092172E+0,
      4.83333942E+0,
      4.80885576E+0,
      4.73708511E+0,
      4.65954270E+0,
      4.62841627E+0,
      4.61493510E+0,
      4.53875445E+0,
      4.50000782E+0,
      4.40430524E+0,
      4.36955558E+0,
      4.27785306E+0,
      4.24630855E+0,
      4.13677781E+0,
      4.05370866E+0,
      4.00225202E+0,
      3.87853128E+0,
      3.85986602E+0,
      3.77831884E+0,
      3.71174349E+0,
      3.63711484E+0,
      3.56317317E+0,
      3.51026542E+0,
      3.41791259E+0,
      3.39395866E+0,
      3.35163500E+0,
      3.28719819E+0,
      3.27946137E+0,
      3.19860321E+0,
      3.15677237E+0,
      3.14833420E+0,
      3.11803839E+0,
      3.07209457E+0,
      3.06300148E+0,
      3.04158882E+0,
      3.00140134E+0,
      2.97070014E+0,
      2.94095779E+0,
      2.92062309E+0,
      2.90530933E+0,
      2.88748891E+0,
      2.84544911E+0,
      2.83545996E+0,
      2.79615924E+0,
      2.79114945E+0,
      2.78949710E+0,
      2.75381413E+0,
      2.74210362E+0,
      2.72039822E+0,
      2.69143781E+0,
      2.68717535E+0,
      2.66647816E+0,
      2.65651143E+0,
      2.62861029E+0,
      2.60672857E+0,
      2.60645111E+0,
      2.60357215E+0,
      2.56601916E+0,
      2.55974279E+0,
      2.54897007E+0,
      2.53669282E+0,
      2.52772729E+0,
      2.51666533E+0,
      2.51098823E+0,
      2.50670044E+0,
      2.50269242E+0,
      2.49348584E+0,
      2.49326628E+0,
      2.48762480E+0,
      2.48419465E+0,
      2.48240636E+0);
      constant T_fall_3third  :real_vector := (
      0.00000000E+0,
   445.00000000E-12,
   480.00000000E-12,
   558.00000000E-12,
   588.00000000E-12,
   723.00000000E-12,
   732.00000000E-12,
   746.00000000E-12,
   899.00000000E-12,
   900.00000000E-12,
   968.00000000E-12,
      1.11000000E-9,
      1.17200000E-9,
      1.19100000E-9,
      1.19300000E-9,
      1.19400000E-9,
      1.23700000E-9,
      1.28500000E-9,
      1.33300000E-9,
      1.38500000E-9,
      1.43000000E-9,
      1.46100000E-9,
      1.48700000E-9,
      1.49200000E-9,
      1.52200000E-9,
      1.58400000E-9,
      1.64900000E-9,
      1.71300000E-9,
      1.75800000E-9,
      1.76400000E-9,
      1.78300000E-9,
      1.83600000E-9,
      1.89000000E-9,
      1.91100000E-9,
      1.92000000E-9,
      1.97000000E-9,
      1.99500000E-9,
      2.05600000E-9,
      2.07800000E-9,
      2.13600000E-9,
      2.15600000E-9,
      2.22600000E-9,
      2.28000000E-9,
      2.31400000E-9,
      2.39800000E-9,
      2.41100000E-9,
      2.46900000E-9,
      2.51800000E-9,
      2.57500000E-9,
      2.63400000E-9,
      2.67800000E-9,
      2.75900000E-9,
      2.78100000E-9,
      2.82100000E-9,
      2.88500000E-9,
      2.89300000E-9,
      2.98300000E-9,
      3.03500000E-9,
      3.04600000E-9,
      3.08700000E-9,
      3.15400000E-9,
      3.16800000E-9,
      3.20200000E-9,
      3.27000000E-9,
      3.32600000E-9,
      3.38400000E-9,
      3.42600000E-9,
      3.45900000E-9,
      3.49900000E-9,
      3.60100000E-9,
      3.62700000E-9,
      3.73700000E-9,
      3.75200000E-9,
      3.75700000E-9,
      3.87200000E-9,
      3.91300000E-9,
      3.99400000E-9,
      4.11400000E-9,
      4.13300000E-9,
      4.23100000E-9,
      4.28200000E-9,
      4.44100000E-9,
      4.58700000E-9,
      4.58900000E-9,
      4.61000000E-9,
      4.93600000E-9,
      5.00300000E-9,
      5.13000000E-9,
      5.30000000E-9,
      5.45900000E-9,
      5.70800000E-9,
      5.86900000E-9,
      6.01300000E-9,
      6.17200000E-9,
      6.69600000E-9,
      6.71300000E-9,
      7.31200000E-9,
      8.05600000E-9,
      9.00104318E-9);
-----------------------------------------------------------------------------
      constant V_rise_3third :real_vector := (
      2.48240636E+0,
      2.48470041E+0,
      2.48441657E+0,
      2.48149555E+0,
      2.47431733E+0,
      2.47103385E+0,
      2.46203190E+0,
      2.45292662E+0,
      2.44895825E+0,
      2.44049418E+0,
      2.43709635E+0,
      2.43798121E+0,
      2.43926648E+0,
      2.44784174E+0,
      2.44880852E+0,
      2.44982257E+0,
      2.46349629E+0,
      2.47303039E+0,
      2.48781632E+0,
      2.49901954E+0,
      2.50879427E+0,
      2.52119271E+0,
      2.55788147E+0,
      2.56409802E+0,
      2.57266343E+0,
      2.60525289E+0,
      2.63919262E+0,
      2.66188427E+0,
      2.67076241E+0,
      2.74548213E+0,
      2.80099582E+0,
      2.87104921E+0,
      2.93531118E+0,
      2.95995598E+0,
      3.01774823E+0,
      3.08652743E+0,
      3.17204843E+0,
      3.20382175E+0,
      3.26245159E+0,
      3.35703109E+0,
      3.37084292E+0,
      3.44799323E+0,
      3.48365092E+0,
      3.55593508E+0,
      3.59247854E+0,
      3.75504008E+0,
      3.76988146E+0,
      3.93247477E+0,
      4.01984402E+0,
      4.04145371E+0,
      4.12665275E+0,
      4.25620052E+0,
      4.28888600E+0,
      4.31451902E+0,
      4.40023324E+0,
      4.48412509E+0,
      4.48941474E+0,
      4.56791393E+0,
      4.63503103E+0,
      4.63884626E+0,
      4.65369674E+0,
      4.70282353E+0,
      4.76321706E+0,
      4.77875281E+0,
      4.81368113E+0,
      4.83808518E+0,
      4.85634992E+0,
      4.88213645E+0,
      4.88917762E+0,
      4.89014718E+0,
      4.90667165E+0,
      4.91759123E+0,
      4.92086844E+0,
      4.93189249E+0,
      4.93687184E+0,
      4.94092401E+0,
      4.94934005E+0,
      4.95459710E+0,
      4.95596136E+0,
      4.96183225E+0,
      4.96618082E+0,
      4.96791601E+0,
      4.96943011E+0,
      4.97160033E+0,
      4.97298816E+0,
      4.97321315E+0,
      4.97235000E+0,
      4.97075260E+0,
      4.96598351E+0,
      4.95989970E+0,
      4.96746768E+0,
      4.97640419E+0,
      4.98637966E+0,
      4.99018982E+0,
      4.99520973E+0,
      4.99799850E+0,
      4.99907829E+0);
      constant T_rise_3third :real_vector := (
      0.00000000E+0,
   184.00000000E-12,
   192.00000000E-12,
   236.00000000E-12,
   285.00000000E-12,
   300.00000000E-12,
   334.00000000E-12,
   364.00000000E-12,
   377.00000000E-12,
   410.00000000E-12,
   439.00000000E-12,
   458.00000000E-12,
   466.00000000E-12,
   492.00000000E-12,
   494.00000000E-12,
   496.00000000E-12,
   517.00000000E-12,
   528.00000000E-12,
   542.00000000E-12,
   551.00000000E-12,
   558.00000000E-12,
   566.00000000E-12,
   586.00000000E-12,
   589.00000000E-12,
   593.00000000E-12,
   607.00000000E-12,
   620.00000000E-12,
   628.00000000E-12,
   631.00000000E-12,
   654.00000000E-12,
   669.00000000E-12,
   686.00000000E-12,
   700.00000000E-12,
   705.00000000E-12,
   716.00000000E-12,
   728.00000000E-12,
   742.00000000E-12,
   747.00000000E-12,
   756.00000000E-12,
   770.00000000E-12,
   772.00000000E-12,
   783.00000000E-12,
   788.00000000E-12,
   798.00000000E-12,
   803.00000000E-12,
   825.00000000E-12,
   827.00000000E-12,
   849.00000000E-12,
   861.00000000E-12,
   864.00000000E-12,
   876.00000000E-12,
   895.00000000E-12,
   900.00000000E-12,
   904.00000000E-12,
   918.00000000E-12,
   933.00000000E-12,
   934.00000000E-12,
   950.00000000E-12,
   966.00000000E-12,
   967.00000000E-12,
   971.00000000E-12,
   986.00000000E-12,
      1.00900000E-9,
      1.01600000E-9,
      1.03400000E-9,
      1.04900000E-9,
      1.06200000E-9,
      1.08400000E-9,
      1.09100000E-9,
      1.09200000E-9,
      1.11100000E-9,
      1.12600000E-9,
      1.13100000E-9,
      1.15000000E-9,
      1.16000000E-9,
      1.16900000E-9,
      1.19100000E-9,
      1.20800000E-9,
      1.21300000E-9,
      1.23900000E-9,
      1.26700000E-9,
      1.28200000E-9,
      1.29900000E-9,
      1.33500000E-9,
      1.38600000E-9,
      1.42000000E-9,
      1.51500000E-9,
      1.59000000E-9,
      1.64100000E-9,
      1.83200000E-9,
      2.23300000E-9,
      2.73800000E-9,
      3.31200000E-9,
      3.59800000E-9,
      4.19100000E-9,
      5.02500000E-9,
      9.00104318E-9);
-----------------------------------------------------------------------------
      constant T_rise_1third  : real_vector := (
      0.00000000E+0,
   446.00000000E-12,
   532.00000000E-12,
   540.00000000E-12,
   595.00000000E-12,
   643.00000000E-12,
   645.00000000E-12,
   646.00000000E-12,
   684.00000000E-12,
   698.00000000E-12,
   711.00000000E-12,
   728.00000000E-12,
   760.00000000E-12,
   767.00000000E-12,
   786.00000000E-12,
   796.00000000E-12,
   804.00000000E-12,
   824.00000000E-12,
   850.00000000E-12,
   869.00000000E-12,
   870.00000000E-12,
   872.00000000E-12,
   887.00000000E-12,
   917.00000000E-12,
   922.00000000E-12,
   946.00000000E-12,
   960.00000000E-12,
   978.00000000E-12,
   981.00000000E-12,
   996.00000000E-12,
   997.00000000E-12,
      1.01600000E-9,
      1.03100000E-9,
      1.05700000E-9,
      1.06400000E-9,
      1.08100000E-9,
      1.11700000E-9,
      1.15300000E-9,
      1.18600000E-9,
      1.19200000E-9,
      1.21300000E-9,
      1.23300000E-9,
      1.28700000E-9,
      1.28800000E-9,
      1.34900000E-9,
      1.39500000E-9,
      1.43200000E-9,
      1.47600000E-9,
      1.49000000E-9,
      1.55900000E-9,
      1.59000000E-9,
      1.68000000E-9,
      1.70000000E-9,
      1.81400000E-9,
      1.81600000E-9,
      1.82100000E-9,
      1.95100000E-9,
      1.95600000E-9,
      1.96200000E-9,
      2.10100000E-9,
      2.12300000E-9,
      2.22000000E-9,
      2.25700000E-9,
      2.28800000E-9,
      2.32400000E-9,
      2.40300000E-9,
      2.43700000E-9,
      2.50800000E-9,
      2.61200000E-9,
      2.62800000E-9,
      2.63300000E-9,
      2.76700000E-9,
      2.83300000E-9,
      2.85400000E-9,
      2.92600000E-9,
      2.97400000E-9,
      3.10800000E-9,
      3.15200000E-9,
      3.23500000E-9,
      3.25800000E-9,
      3.42300000E-9,
      3.42400000E-9,
      3.53300000E-9,
      3.66300000E-9,
      3.68800000E-9,
      3.75300000E-9,
      3.80300000E-9,
      3.99800000E-9,
      4.12400000E-9,
      4.17600000E-9,
      4.36800000E-9,
      4.41100000E-9,
      4.74200000E-9,
      4.82400000E-9,
      5.12700000E-9,
      5.31900000E-9,
      5.58500000E-9,
      6.04800000E-9,
      6.77900000E-9,
      9.00000000E-9);
      constant V_rise_1third  : real_vector := (
    599.79555323E-3,
    593.91051722E-3,
    594.56271194E-3,
    595.14509217E-3,
    602.46633509E-3,
    614.76513537E-3,
    615.42518161E-3,
    615.75878086E-3,
    631.17862610E-3,
    638.38224622E-3,
    646.11023929E-3,
    657.94063610E-3,
    686.41428516E-3,
    693.95230367E-3,
    717.32092323E-3,
    731.60013193E-3,
    744.18137678E-3,
    780.98573715E-3,
    843.01653806E-3,
    902.57015776E-3,
    906.12572283E-3,
    913.43615744E-3,
    975.22638850E-3,
      1.13445334E+0,
      1.16210326E+0,
      1.28838402E+0,
      1.35337521E+0,
      1.42384404E+0,
      1.43408765E+0,
      1.47769854E+0,
      1.48022008E+0,
      1.52182890E+0,
      1.54735908E+0,
      1.58045785E+0,
      1.58746633E+0,
      1.60181422E+0,
      1.62270176E+0,
      1.63485572E+0,
      1.64116126E+0,
      1.64194335E+0,
      1.64388919E+0,
      1.64474907E+0,
      1.64537392E+0,
      1.64537207E+0,
      1.64474286E+0,
      1.64419709E+0,
      1.64510598E+0,
      1.64593310E+0,
      1.64644719E+0,
      1.65368121E+0,
      1.66003431E+0,
      1.69027165E+0,
      1.69932843E+0,
      1.76586069E+0,
      1.76723969E+0,
      1.77071786E+0,
      1.87499395E+0,
      1.87949175E+0,
      1.88493334E+0,
      2.02316595E+0,
      2.04697915E+0,
      2.15739357E+0,
      2.20159103E+0,
      2.23935015E+0,
      2.28391174E+0,
      2.38373080E+0,
      2.42727334E+0,
      2.51869321E+0,
      2.64756833E+0,
      2.66616903E+0,
      2.67192692E+0,
      2.81820556E+0,
      2.88357735E+0,
      2.90283720E+0,
      2.96301381E+0,
      2.99847521E+0,
      3.08134181E+0,
      3.10426557E+0,
      3.14283019E+0,
      3.15255010E+0,
      3.21207299E+0,
      3.21238583E+0,
      3.24355097E+0,
      3.27418305E+0,
      3.27937800E+0,
      3.29195982E+0,
      3.30079829E+0,
      3.32937279E+0,
      3.34374623E+0,
      3.34891399E+0,
      3.36480470E+0,
      3.36777078E+0,
      3.38514942E+0,
      3.38827067E+0,
      3.39697206E+0,
      3.40075361E+0,
      3.40448098E+0,
      3.40828863E+0,
      3.41082140E+0,
      3.41205122E+0);
-----------------------------------------------------------------------------
      constant T_fall_1third : real_vector := (
      0.00000000E+0,
   417.00000000E-12,
   568.00000000E-12,
   657.00000000E-12,
   692.00000000E-12,
   726.00000000E-12,
   758.00000000E-12,
   789.00000000E-12,
   802.00000000E-12,
   818.00000000E-12,
   831.00000000E-12,
   844.00000000E-12,
   862.00000000E-12,
   880.00000000E-12,
   884.00000000E-12,
   924.00000000E-12,
   959.00000000E-12,
   962.00000000E-12,
   970.00000000E-12,
   998.00000000E-12,
   999.00000000E-12,
      1.01300000E-9,
      1.02700000E-9,
      1.03200000E-9,
      1.05600000E-9,
      1.05700000E-9,
      1.06000000E-9,
      1.08200000E-9,
      1.08700000E-9,
      1.10700000E-9,
      1.11800000E-9,
      1.14900000E-9,
      1.15300000E-9,
      1.19400000E-9,
      1.19600000E-9,
      1.20000000E-9,
      1.23200000E-9,
      1.23700000E-9,
      1.26800000E-9,
      1.30100000E-9,
      1.30700000E-9,
      1.31300000E-9,
      1.34600000E-9,
      1.38000000E-9,
      1.38600000E-9,
      1.42600000E-9,
      1.43900000E-9,
      1.44600000E-9,
      1.46400000E-9,
      1.48700000E-9,
      1.50200000E-9,
      1.53300000E-9,
      1.54900000E-9,
      1.58200000E-9,
      1.61600000E-9,
      1.63100000E-9,
      1.66800000E-9,
      1.67000000E-9,
      1.68100000E-9,
      1.71900000E-9,
      1.73100000E-9,
      1.76200000E-9,
      1.78100000E-9,
      1.78700000E-9,
      1.83300000E-9,
      1.85400000E-9,
      1.86700000E-9,
      1.96200000E-9,
      2.06300000E-9,
      2.07400000E-9,
      2.08500000E-9,
      2.15800000E-9,
      2.18100000E-9,
      2.22200000E-9,
      2.29400000E-9,
      2.30400000E-9,
      2.39600000E-9,
      2.50200000E-9,
      2.57100000E-9,
      2.57600000E-9,
      2.62200000E-9,
      2.75800000E-9,
      2.85000000E-9,
      2.88200000E-9,
      2.93800000E-9,
      2.95100000E-9,
      3.18700000E-9,
      3.20500000E-9,
      3.41900000E-9,
      3.47900000E-9,
      3.61000000E-9,
      3.83300000E-9,
      4.12600000E-9,
      4.26300000E-9,
      4.76300000E-9,
      4.79400000E-9,
      5.42200000E-9,
      5.56200000E-9,
      6.23300000E-9,
      9.00000000E-9);
      constant V_fall_1third : real_vector := (
      3.41205122E+0,
      3.41297977E+0,
      3.42017537E+0,
      3.42313264E+0,
      3.42149423E+0,
      3.41742694E+0,
      3.41081619E+0,
      3.40117759E+0,
      3.39602669E+0,
      3.38861224E+0,
      3.38141255E+0,
      3.37305693E+0,
      3.35944616E+0,
      3.34332241E+0,
      3.33938211E+0,
      3.29234569E+0,
      3.23832711E+0,
      3.23309041E+0,
      3.21861845E+0,
      3.16194131E+0,
      3.15972662E+0,
      3.12733618E+0,
      3.09202192E+0,
      3.07864504E+0,
      3.00796915E+0,
      3.00477007E+0,
      2.99508933E+0,
      2.91896155E+0,
      2.90041838E+0,
      2.82125447E+0,
      2.77566652E+0,
      2.64844186E+0,
      2.63230553E+0,
      2.47209839E+0,
      2.46457458E+0,
      2.44962004E+0,
      2.33481221E+0,
      2.31770843E+0,
      2.21705934E+0,
      2.12070425E+0,
      2.10441585E+0,
      2.08850993E+0,
      2.00786219E+0,
      1.93672897E+0,
      1.92540426E+0,
      1.85889605E+0,
      1.84049601E+0,
      1.83119625E+0,
      1.80914620E+0,
      1.78448807E+0,
      1.77059969E+0,
      1.74559296E+0,
      1.73392846E+0,
      1.71084211E+0,
      1.68879422E+0,
      1.67868142E+0,
      1.65106055E+0,
      1.64944875E+0,
      1.64036029E+0,
      1.60611713E+0,
      1.59441456E+0,
      1.56232981E+0,
      1.54142116E+0,
      1.53463461E+0,
      1.47991460E+0,
      1.45349917E+0,
      1.43674377E+0,
      1.30737412E+0,
      1.17685893E+0,
      1.16329639E+0,
      1.14982686E+0,
      1.06426359E+0,
      1.04004184E+0,
      1.00087452E+0,
    943.39318442E-3,
    936.38952336E-3,
    880.72168528E-3,
    831.43072384E-3,
    805.44178618E-3,
    803.70988292E-3,
    788.62804897E-3,
    751.56200084E-3,
    731.48937624E-3,
    725.26588427E-3,
    715.19257185E-3,
    712.99220353E-3,
    680.37047506E-3,
    678.35830389E-3,
    658.26917708E-3,
    653.70452712E-3,
    645.02379370E-3,
    633.50341101E-3,
    622.86249039E-3,
    619.15199977E-3,
    610.07225643E-3,
    609.67909020E-3,
    604.29115762E-3,
    603.56728785E-3,
    601.41272016E-3,
    599.79555323E-3);
-----------------------------------------------------------------------------
      constant T_fall_2third  : real_vector := (
      0.00000000E+0,
   387.00000000E-12,
   480.00000000E-12,
   569.00000000E-12,
   676.00000000E-12,
   724.00000000E-12,
   768.00000000E-12,
   813.00000000E-12,
   834.00000000E-12,
   855.00000000E-12,
   913.00000000E-12,
   942.00000000E-12,
   963.00000000E-12,
   991.00000000E-12,
      1.00700000E-9,
      1.04100000E-9,
      1.04400000E-9,
      1.07200000E-9,
      1.10200000E-9,
      1.12400000E-9,
      1.13200000E-9,
      1.13300000E-9,
      1.19100000E-9,
      1.19400000E-9,
      1.23800000E-9,
      1.24900000E-9,
      1.27000000E-9,
      1.30400000E-9,
      1.32000000E-9,
      1.34400000E-9,
      1.35400000E-9,
      1.38400000E-9,
      1.40500000E-9,
      1.41200000E-9,
      1.42500000E-9,
      1.44900000E-9,
      1.45800000E-9,
      1.49800000E-9,
      1.51100000E-9,
      1.53100000E-9,
      1.59500000E-9,
      1.61800000E-9,
      1.64300000E-9,
      1.68200000E-9,
      1.69500000E-9,
      1.74800000E-9,
      1.79100000E-9,
      1.81000000E-9,
      1.81100000E-9,
      1.84300000E-9,
      1.87700000E-9,
      1.95300000E-9,
      1.97000000E-9,
      2.00900000E-9,
      2.02700000E-9,
      2.08300000E-9,
      2.09800000E-9,
      2.15500000E-9,
      2.16100000E-9,
      2.21700000E-9,
      2.24600000E-9,
      2.29200000E-9,
      2.35300000E-9,
      2.37600000E-9,
      2.42400000E-9,
      2.44600000E-9,
      2.50000000E-9,
      2.57400000E-9,
      2.59400000E-9,
      2.69600000E-9,
      2.79000000E-9,
      2.81400000E-9,
      2.87200000E-9,
      2.94100000E-9,
      2.96000000E-9,
      3.05800000E-9,
      3.08500000E-9,
      3.11100000E-9,
      3.19700000E-9,
      3.28000000E-9,
      3.31900000E-9,
      3.48000000E-9,
      3.55700000E-9,
      3.58600000E-9,
      3.78900000E-9,
      3.89000000E-9,
      3.95700000E-9,
      4.02100000E-9,
      4.29400000E-9,
      4.31900000E-9,
      4.66900000E-9,
      4.79200000E-9,
      5.08100000E-9,
      5.26800000E-9,
      5.37400000E-9,
      5.57100000E-9,
      6.14100000E-9,
      6.14200000E-9,
      6.84800000E-9,
      9.00000000E-9);
      constant V_fall_2third  : real_vector := (
      4.27062600E+0,
      4.26960794E+0,
      4.27029683E+0,
      4.27396851E+0,
      4.28162083E+0,
      4.28448317E+0,
      4.28610966E+0,
      4.28633872E+0,
      4.28541564E+0,
      4.28330749E+0,
      4.27054067E+0,
      4.25990008E+0,
      4.25019617E+0,
      4.23472166E+0,
      4.22455697E+0,
      4.19960599E+0,
      4.19717650E+0,
      4.17247962E+0,
      4.14158081E+0,
      4.11565390E+0,
      4.10554308E+0,
      4.10425085E+0,
      4.01631208E+0,
      4.01095704E+0,
      3.91968894E+0,
      3.89252310E+0,
      3.83615143E+0,
      3.74747087E+0,
      3.70838714E+0,
      3.65372787E+0,
      3.63247551E+0,
      3.57438633E+0,
      3.53885902E+0,
      3.52793894E+0,
      3.50885448E+0,
      3.47747507E+0,
      3.46706184E+0,
      3.42744161E+0,
      3.41627881E+0,
      3.39997862E+0,
      3.35484073E+0,
      3.33723050E+0,
      3.31653872E+0,
      3.28084724E+0,
      3.26802588E+0,
      3.21122040E+0,
      3.16024087E+0,
      3.13648426E+0,
      3.13521377E+0,
      3.09363194E+0,
      3.04761585E+0,
      2.93930960E+0,
      2.91427263E+0,
      2.85600290E+0,
      2.82878921E+0,
      2.74323385E+0,
      2.72016398E+0,
      2.63229055E+0,
      2.62304135E+0,
      2.53697471E+0,
      2.49271263E+0,
      2.42316226E+0,
      2.33281608E+0,
      2.30026074E+0,
      2.23594792E+0,
      2.20798846E+0,
      2.14283177E+0,
      2.06017306E+0,
      2.03893993E+0,
      1.93678968E+0,
      1.85100135E+0,
      1.83113811E+0,
      1.78729910E+0,
      1.74196373E+0,
      1.73061328E+0,
      1.67857704E+0,
      1.66591526E+0,
      1.65431782E+0,
      1.61966601E+0,
      1.59085229E+0,
      1.57865282E+0,
      1.53573133E+0,
      1.51873190E+0,
      1.51282722E+0,
      1.47786227E+0,
      1.46390680E+0,
      1.45567515E+0,
      1.44848796E+0,
      1.42390646E+0,
      1.42206690E+0,
      1.40165970E+0,
      1.39638172E+0,
      1.38673799E+0,
      1.38209360E+0,
      1.37989406E+0,
      1.37648499E+0,
      1.37015288E+0,
      1.37014513E+0,
      1.36644165E+0,
      1.36382034E+0);
-----------------------------------------------------------------------------
      constant T_rise_2third : real_vector := (
      0.00000000E+0,
   411.00000000E-12,
   494.00000000E-12,
   500.00000000E-12,
   529.00000000E-12,
   552.00000000E-12,
   559.00000000E-12,
   583.00000000E-12,
   597.00000000E-12,
   600.00000000E-12,
   605.00000000E-12,
   624.00000000E-12,
   642.00000000E-12,
   657.00000000E-12,
   668.00000000E-12,
   680.00000000E-12,
   712.00000000E-12,
   713.00000000E-12,
   722.00000000E-12,
   740.00000000E-12,
   742.00000000E-12,
   761.00000000E-12,
   763.00000000E-12,
   764.00000000E-12,
   779.00000000E-12,
   788.00000000E-12,
   801.00000000E-12,
   809.00000000E-12,
   820.00000000E-12,
   826.00000000E-12,
   849.00000000E-12,
   855.00000000E-12,
   885.00000000E-12,
   888.00000000E-12,
   915.00000000E-12,
   918.00000000E-12,
   936.00000000E-12,
   942.00000000E-12,
   947.00000000E-12,
   964.00000000E-12,
   986.00000000E-12,
   989.00000000E-12,
      1.00500000E-9,
      1.01200000E-9,
      1.04000000E-9,
      1.07400000E-9,
      1.11200000E-9,
      1.12800000E-9,
      1.14100000E-9,
      1.16900000E-9,
      1.19500000E-9,
      1.20000000E-9,
      1.22100000E-9,
      1.25300000E-9,
      1.28900000E-9,
      1.35100000E-9,
      1.41700000E-9,
      1.43500000E-9,
      1.48400000E-9,
      1.54800000E-9,
      1.61600000E-9,
      1.62400000E-9,
      1.70400000E-9,
      1.70500000E-9,
      1.79000000E-9,
      1.88400000E-9,
      1.96600000E-9,
      1.96900000E-9,
      1.98400000E-9,
      2.07800000E-9,
      2.08500000E-9,
      2.20000000E-9,
      2.24200000E-9,
      2.30400000E-9,
      2.32100000E-9,
      2.43000000E-9,
      2.44600000E-9,
      2.44900000E-9,
      2.60800000E-9,
      2.67500000E-9,
      2.81800000E-9,
      2.84300000E-9,
      2.95300000E-9,
      2.97700000E-9,
      3.08800000E-9,
      3.15300000E-9,
      3.29400000E-9,
      3.35300000E-9,
      3.41000000E-9,
      3.65600000E-9,
      3.73200000E-9,
      3.79800000E-9,
      4.01100000E-9,
      4.28000000E-9,
      4.42900000E-9,
      4.90000000E-9,
      4.93300000E-9,
      5.56600000E-9,
      6.25300000E-9,
      9.00000000E-9);
      constant V_rise_2third : real_vector := (
      1.36382034E+0,
      1.34857190E+0,
      1.35079542E+0,
      1.35190406E+0,
      1.35967362E+0,
      1.36907551E+0,
      1.37257517E+0,
      1.38706488E+0,
      1.39747982E+0,
      1.39991342E+0,
      1.40414774E+0,
      1.42227637E+0,
      1.44278978E+0,
      1.46274010E+0,
      1.47923468E+0,
      1.49927769E+0,
      1.56562196E+0,
      1.56807194E+0,
      1.59117390E+0,
      1.64431068E+0,
      1.65085218E+0,
      1.72058798E+0,
      1.72883474E+0,
      1.73300921E+0,
      1.80129129E+0,
      1.84685196E+0,
      1.91880789E+0,
      1.96701399E+0,
      2.03938973E+0,
      2.08123515E+0,
      2.24798215E+0,
      2.29244323E+0,
      2.51442017E+0,
      2.53624223E+0,
      2.72465329E+0,
      2.74439492E+0,
      2.85574562E+0,
      2.88981537E+0,
      2.91688856E+0,
      2.99955536E+0,
      3.08369410E+0,
      3.09308948E+0,
      3.13693593E+0,
      3.15324572E+0,
      3.20490907E+0,
      3.24645954E+0,
      3.27524416E+0,
      3.28357876E+0,
      3.28911596E+0,
      3.29808924E+0,
      3.30366785E+0,
      3.30450289E+0,
      3.30729922E+0,
      3.30970982E+0,
      3.31056639E+0,
      3.31026483E+0,
      3.30904718E+0,
      3.30868675E+0,
      3.30788903E+0,
      3.30919129E+0,
      3.31244192E+0,
      3.31326921E+0,
      3.32885370E+0,
      3.32913840E+0,
      3.36133116E+0,
      3.41434878E+0,
      3.47360796E+0,
      3.47598133E+0,
      3.48804735E+0,
      3.57083229E+0,
      3.57745648E+0,
      3.68802452E+0,
      3.72753140E+0,
      3.78471944E+0,
      3.79959272E+0,
      3.88390971E+0,
      3.89471439E+0,
      3.89669826E+0,
      3.98579608E+0,
      4.01562930E+0,
      4.06816548E+0,
      4.07605436E+0,
      4.10702317E+0,
      4.11305233E+0,
      4.13804581E+0,
      4.15073000E+0,
      4.17413933E+0,
      4.18250107E+0,
      4.18988428E+0,
      4.21526374E+0,
      4.22135872E+0,
      4.22610719E+0,
      4.23854164E+0,
      4.24943481E+0,
      4.25379343E+0,
      4.26251403E+0,
      4.26291927E+0,
      4.26774943E+0,
      4.26964608E+0,
      4.27062600E+0);
-----------------------------------------------------------------------------
           ------------------------------------------------------------------
           -- V_fixture and R_fixture values
           ------------------------------------------------------------------
      constant Vfx_rise_0third : real := 0.0;
      constant Vfx_fall_0third : real := 0.0;
      constant Vfx_rise_1third : real := 1.667;
      constant Vfx_fall_1third : real := 1.667;
      constant Vfx_fall_2third : real := 3.333;
      constant Vfx_rise_2third : real := 3.333;
      constant Vfx_fall_3third : real := 5.0;
      constant Vfx_rise_3third : real := 5.0;

      constant Rfx_rise_0third : real := 50.0;
      constant Rfx_fall_0third : real := 50.0;
      constant Rfx_rise_1third : real := 50.0;
      constant Rfx_fall_1third : real := 50.0;
      constant Rfx_fall_2third : real := 50.0;
      constant Rfx_rise_2third : real := 50.0;
      constant Rfx_fall_3third : real := 50.0;
      constant Rfx_rise_3third : real := 50.0;
--***************************************************************************
--***************************************************************************
--***************************************************************************
   ------------------------------------------------------------------
   -- In the actual version, T_common is obtained from only
   -- two pairs of VT-tables!!!
   ------------------------------------------------------------------
   constant T_common        : real_vector := Common_time(Delta_t, T_rise_0third,  T_fall_0third, T_fall_3third, T_rise_3third);

   constant V_rise_0third_common : real_vector := Common_wfm(T_common, V_rise_0third, T_rise_0third);
   constant V_fall_0third_common : real_vector := Common_wfm(T_common, V_fall_0third, T_fall_0third);
   constant V_fall_1third_common : real_vector := Common_wfm(T_common, V_fall_1third, T_fall_1third);
   constant V_rise_1third_common : real_vector := Common_wfm(T_common, V_rise_1third, T_rise_1third);
   constant V_rise_2third_common : real_vector := Common_wfm(T_common, V_rise_2third, T_rise_2third);
   constant V_fall_2third_common : real_vector := Common_wfm(T_common, V_fall_2third, T_fall_2third);
   constant V_fall_3third_common : real_vector := Common_wfm(T_common, V_fall_3third, T_fall_3third);
   constant V_rise_3third_common : real_vector := Common_wfm(T_common, V_rise_3third, T_rise_3third);

   constant  K_pu_on_A  : real_vector := Coeff("K_pu_on",  V_rise_0third_common, V_rise_1third_common, T_common, Rfx_rise_0third, Rfx_rise_1third, Vfx_rise_0third, Vfx_rise_1third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
   constant  K_pd_off_A : real_vector := Coeff("K_pd_off", V_rise_0third_common, V_rise_1third_common, T_common, Rfx_rise_0third, Rfx_rise_1third, Vfx_rise_0third, Vfx_rise_1third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
   constant  K_pd_on_A  : real_vector := Coeff("K_pd_on",  V_fall_0third_common, V_fall_1third_common, T_common, Rfx_fall_0third, Rfx_fall_1third, Vfx_fall_0third, Vfx_fall_1third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
   constant  K_pu_off_A : real_vector := Coeff("K_pu_off", V_fall_0third_common, V_fall_1third_common, T_common, Rfx_fall_0third, Rfx_fall_1third, Vfx_fall_0third, Vfx_fall_1third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);

   constant  K_pu_on_B  : real_vector := Coeff("K_pu_on",  V_rise_1third_common, V_rise_2third_common, T_common, Rfx_rise_1third, Rfx_rise_2third, Vfx_rise_1third, Vfx_rise_2third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
   constant  K_pd_off_B : real_vector := Coeff("K_pd_off", V_rise_1third_common, V_rise_2third_common, T_common, Rfx_rise_1third, Rfx_rise_2third, Vfx_rise_1third, Vfx_rise_2third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
   constant  K_pd_on_B  : real_vector := Coeff("K_pd_on",  V_fall_1third_common, V_fall_2third_common, T_common, Rfx_fall_1third, Rfx_fall_2third, Vfx_fall_1third, Vfx_fall_2third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
   constant  K_pu_off_B : real_vector := Coeff("K_pu_off", V_fall_1third_common, V_fall_2third_common, T_common, Rfx_fall_1third, Rfx_fall_2third, Vfx_fall_1third, Vfx_fall_2third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);

   constant  K_pu_on_C  : real_vector := Coeff("K_pu_on",  V_rise_2third_common, V_rise_3third_common, T_common, Rfx_rise_2third, Rfx_rise_3third, Vfx_rise_2third, Vfx_rise_3third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
   constant  K_pd_off_C : real_vector := Coeff("K_pd_off", V_rise_2third_common, V_rise_3third_common, T_common, Rfx_rise_2third, Rfx_rise_3third, Vfx_rise_2third, Vfx_rise_3third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
   constant  K_pd_on_C  : real_vector := Coeff("K_pd_on",  V_fall_2third_common, V_fall_3third_common, T_common, Rfx_fall_2third, Rfx_fall_3third, Vfx_fall_2third, Vfx_fall_3third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
   constant  K_pu_off_C : real_vector := Coeff("K_pu_off", V_fall_2third_common, V_fall_3third_common, T_common, Rfx_fall_2third, Rfx_fall_3third, Vfx_fall_2third, Vfx_fall_3third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);

--===========================================================================
   --------------------------------------------------------------------------
   -- This is just to recreate the old two table style (to compare the results).
   --------------------------------------------------------------------------
--   constant  K_pu_on_A  : real_vector := Coeff("K_pu_on",  V_rise_0third_common, V_rise_3third_common, T_common, Rfx_rise_0third, Rfx_rise_3third, Vfx_rise_0third, Vfx_rise_3third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
--   constant  K_pd_off_A : real_vector := Coeff("K_pd_off", V_rise_0third_common, V_rise_3third_common, T_common, Rfx_rise_0third, Rfx_rise_3third, Vfx_rise_0third, Vfx_rise_3third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
--   constant  K_pd_on_A  : real_vector := Coeff("K_pd_on",  V_fall_0third_common, V_fall_3third_common, T_common, Rfx_fall_0third, Rfx_fall_3third, Vfx_fall_0third, Vfx_fall_3third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);
--   constant  K_pu_off_A : real_vector := Coeff("K_pu_off", V_fall_0third_common, V_fall_3third_common, T_common, Rfx_fall_0third, Rfx_fall_3third, Vfx_fall_0third, Vfx_fall_3third, I_pu, V_pu, I_pd, V_pd, V_pu_ref, V_pd_ref, C_comp);

--   constant  K_pu_on_B  : real_vector := K_pu_on_A;
--   constant  K_pd_off_B : real_vector := K_pd_off_A;
--   constant  K_pd_on_B  : real_vector := K_pd_on_A;
--   constant  K_pu_off_B : real_vector := K_pu_off_A;

--   constant  K_pu_on_C  : real_vector := K_pu_on_A;
--   constant  K_pd_off_C : real_vector := K_pd_off_A;
--   constant  K_pd_on_C  : real_vector := K_pd_on_A;
--   constant  K_pu_off_C : real_vector := K_pu_off_A;
--===========================================================================

begin
--===========================================================================
   Catch: process (In_D, En_D) is
   --------------------------------------------------------------------------
   begin
      Rcv_D <= In_D;                             -- Dummy receiver logic

      if (In_D'event) then In_time <= now;       -- Save time of In_D events
      end if;

      if (En_D'event) then En_time <= now;       -- Save time of En_D events
      end if;

      Event_time  <= now;                        -- Save time of either event
      -----------------------------------------------------------------------
      if (En_D = '1') and (In_D = '1') then      -- Find logic state
         State_D <= '1';
      elsif (En_D = '1') and (In_D = '0') then
         State_D <= '0';
      elsif (En_D = '0') then
         State_D <= 'Z';
      end if;
   --------------------------------------------------------------------------
   end process Catch;
--===========================================================================
  Logic: process (State_D, In_time, En_time) is
  ---------------------------------------------------------------------------
  -- This process handles the logic events and sets the signals that control
  -- the analog equations.  The logic includes all combinations of switching
  -- high-to-low or low-to-high with the enable on/off, going in and out of
  -- 3-state mode while the input is high/low, and input and enable
  -- switching together.
  ---------------------------------------------------------------------------
  begin
  ---------------------------------------------------------------------------
  if (domain = quiescent_domain) then            -- Setting initial states
    if (State_D = 'Z') then                      -- 3-state
      pu_on       <= '0';
      pd_off      <= '0';
      pd_on       <= '0';
      pu_off      <= '0';
    elsif (State_D = '1') then                   -- Drive high
      pu_on       <= '1';
      pd_off      <= '1';
      pd_on       <= '0';
      pu_off      <= '0';
      if (V_pad'above(V_rise_2third_common(1))) then
         Zone_ABC <= 'C';
      elsif (V_pad'above(V_rise_1third_common(1))) then
         Zone_ABC <= 'B';
      else
         Zone_ABC <= 'A';
      end if;
    elsif (State_D = '0') then                   -- Drive low
      pu_on       <= '0';
      pd_off      <= '0';
      pd_on       <= '1';
      pu_off      <= '1';
      if (V_pad'above(V_fall_2third_common(1))) then
         Zone_ABC <= 'C';
      elsif (V_pad'above(V_fall_1third_common(1))) then
         Zone_ABC <= 'B';
      else
         Zone_ABC <= 'A';
      end if;
    end if;
                                                 -- Normal operation
  elsif (State_D = '1') then                     -- En_D high, In_D high after
    if (In_time > En_time) then                  -- In_D changed (En_D steady)
      pu_on       <= '1';
      pd_off      <= '1';
      pd_on       <= '0';
      pu_off      <= '0';
    elsif (En_time > In_time) then               -- En_D changed (In_D steady)
      pu_on       <= '1';
      pd_off      <= '0';
      pd_on       <= '0';
      pu_off      <= '0';
    elsif (En_time = In_time) then               -- En_D and In_D both changed
      pu_on       <= '1';
      pd_off      <= '0';
      pd_on       <= '0';
      pu_off      <= '0';
    end if;
    if (V_pad'above(V_rise_2third_common(1))) then
       Zone_ABC <= 'C';
    elsif (V_pad'above(V_rise_1third_common(1))) then
       Zone_ABC <= 'B';
    else
       Zone_ABC <= 'A';
    end if;

  elsif (State_D = '0') then                     -- En_D high, In_D low after
    if (In_time > En_time) then                  -- In_D changed (En_D steady)
      pu_on       <= '0';
      pd_off      <= '0';
      pd_on       <= '1';
      pu_off      <= '1';
    elsif (En_time > In_time) then               -- En_D changed (In_D steady)
      pu_on       <= '0';
      pd_off      <= '0';
      pd_on       <= '1';
      pu_off      <= '0';
    elsif (En_time = In_time) then               -- En_D and In_D both changed
      pu_on       <= '0';
      pd_off      <= '0';
      pd_on       <= '1';
      pu_off      <= '0';
    end if;
    if (V_pad'above(V_fall_2third_common(1))) then
       Zone_ABC <= 'C';
    elsif (V_pad'above(V_fall_1third_common(1))) then
       Zone_ABC <= 'B';
    else
       Zone_ABC <= 'A';
    end if;

  elsif (State_D = 'Z') and (In_D = '1') then    -- En_D low, In_D high after
    if (En_time > In_time) then                  -- En_D changed (In_D steady)
      pu_on       <= '0';
      pd_off      <= '0';
      pd_on       <= '0';
      pu_off      <= '1';
    elsif (En_time = In_time) then               -- En_D and In_D both changed
      pu_on       <= '0';
      pd_off      <= '1';
      pd_on       <= '0';
      pu_off      <= '0';
    end if;
    if (V_pad'above(V_rise_2third_common(1))) then
       Zone_ABC <= 'C';
    elsif (V_pad'above(V_rise_1third_common(1))) then
       Zone_ABC <= 'B';
    else
       Zone_ABC <= 'A';
    end if;

  elsif (State_D = 'Z') and (In_D = '0') then    -- En_D low, In_D low after
    if (En_time > In_time) then                  -- En_D changed (In_D steady)
      pu_on       <= '0';
      pd_off      <= '1';
      pd_on       <= '0';
      pu_off      <= '0';
    elsif (En_time = In_time) then               -- En_D and In_D both changed
      pu_on       <= '0';
      pd_off      <= '0';
      pd_on       <= '0';
      pu_off      <= '1';
    end if;
    if (V_pad'above(V_fall_2third_common(1))) then
       Zone_ABC <= 'C';
    elsif (V_pad'above(V_fall_1third_common(1))) then
       Zone_ABC <= 'B';
    else
       Zone_ABC <= 'A';
    end if;

  end if;
  ---------------------------------------------------------------------------
  end process Logic;
--===========================================================================
   break on pu_on;
   break on pu_off;
   break on pd_on;
   break on pd_off;
--===========================================================================
---Simultaneous statements---
--===========================================================================
   --------------------------------------------------------------------------
   ------Transistors---------------------------------------------------------
   --------------------------------------------------------------------------
   Pull_Up : entity work.IV_transistor(tabled_IV)
                generic map(I => I_pu, V => V_pu, direction => minus2plus,
                            Kxx_on_A => K_pu_on_A, Kxx_off_A => K_pu_off_A,
                            Kxx_on_B => K_pu_on_B, Kxx_off_B => K_pu_off_B,
                            Kxx_on_C => K_pu_on_C, Kxx_off_C => K_pu_off_C,
                            Common_Time => T_common)
                port map(Plus_node  => PU_ref,
                         Minus_node => IO,
                         ZoneABC    => Zone_ABC,
                         px_on      => pu_on,
                         px_off     => pu_off);

   Pull_Down : entity work.IV_transistor(tabled_IV)
                generic map(I => I_pd, V => V_pd, direction => plus2minus,
                            Kxx_on_A => K_pd_on_A, Kxx_off_A => K_pd_off_A,
                            Kxx_on_B => K_pd_on_B, Kxx_off_B => K_pd_off_B,
                            Kxx_on_C => K_pd_on_C, Kxx_off_C => K_pd_off_C,
                            Common_Time => T_common)
                port map(Plus_node  => IO,
                         Minus_node => PD_ref,
                         ZoneABC    => Zone_ABC,
                         px_on      => pd_on,
                         px_off     => pd_off);
   --------------------------------------------------------------------------
   ------Clamps--------------------------------------------------------------
   --------------------------------------------------------------------------
   GND_clamp : entity work.IV_clamp(tabled_IV)
                  generic map(I => I_gc, V => V_gc, direction => plus2minus)    -- minus2plus)
                  port map(Plus_node => IO, Minus_node => GC_ref);

   PWR_clamp : entity work.IV_clamp(tabled_IV)
                  generic map(I => I_pc, V => V_pc, direction => minus2plus)    -- plus2minus)
                  port map(Plus_node => PC_ref, Minus_node => IO);
   --------------------------------------------------------------------------
   ------Standard die-capacitance implementation-----------------------------
   --------------------------------------------------------------------------
   Die_capacitance_gc : entity work.Die_cap(C_or_C_NL)
                           generic map(Which => Which_C_comp, C => C_comp)    -- C_comp*K_C_comp_gc)
                           port map(Plus_node => IO, Minus_node => GC_ref, V_nl => V_pad);
   --------------------------------------------------------------------------
   ------Splitted die-capacitance implementation-----------------------------
   --------------------------------------------------------------------------
--   Die_capacitance_gc : entity work.Die_cap(C_or_C_NL)
--                           generic map(Which => Which_C_comp, C => C_comp*K_C_comp_gc)
--                           port map(Plus_node => IO, Minus_node => GC_ref, V_nl => V_pad);
--   Die_capacitance_pc : entity work.Die_cap(C_or_C_NL)
--                           generic map(Which => Which_C_comp, C => C_comp*K_C_comp_pc) 
--                           port map(Plus_node => PC_ref, Minus_node => IO, V_nl => V_pad);
--   Die_capacitance_pu : entity work.Die_cap(C_or_C_NL)
--                           generic map(Which => Which_C_comp, C => C_comp*K_C_comp_pu)
--                           port map(Plus_node => PU_ref, Minus_node => IO, V_nl => V_pad);
--   Die_capacitance_pd : entity work.Die_cap(C_or_C_NL)
--                           generic map(Which => Which_C_comp, C => C_comp*K_C_comp_pd)
--                           port map(Plus_node => IO, Minus_node => PD_ref, V_nl => V_pad);
   --------------------------------------------------------------------------
end architecture IO_buffer;
--===========================================================================
