// 'E2L_inhconn.vams' - Verilog-AMS connection module.
// last revised:  1/30/04 (ronv)
//
// REVISION HISTORY:
// Created:  3/13/02 ronv
// Updated:  4/17/02 ronv - allow initial X state.
// Updated:  6/20/02 ronv - matched up with L2E writeback logic.
// Updated:  8/30/02 ronv - removed optional input cap
// Updated:  9/14/02 ronv - added tr for ttol reference, loosened default ttol
// Updated: 10/22/02 ronv - updated from @cross to @above format, limit vtol
// Updated: 10/30/02 ronv - improved initialization
// Updated:  2/06/03 ronv - added hysteresis to A2D conversion
// Updated:  11/17/03 ricks - modified for supply sensitivity use
// Updated:  1/30/04 ronv - scaling to simplify & correct Vss sensitivities 
// Updated:  1/13/05 tklee - modified for Inherited Connections
//
//============================================================================
// E2L_inhconn (Ain, Dout)
// - Electrical-to-Logic connect module with Inherited Connections.
//
// DESCRIPTION:
//  Reasonably comprehensive electrical-to-logic conversion routine.
//  Logic output will change to X if input stays between thresholds too long.
//
//  For this supply sensitive format for the model, the fixed levels have
//  been replaced by scale factors which map voltage levels of 0=\vss! to
//  1=vdd! .
//
// INCLUDE FILES:
`include "disciplines.vams"
`timescale 1ns / 100ps

//============================================================================
connectmodule E2L_inhconn (Ain, Dout);
  input Ain; electrical Ain;                     // electrical input
  output Dout; \logic Dout;                      // logic output

// Inherited vdd! and vss!
  electrical
     (* integer inh_conn_prop_name="vdd";
        integer inh_conn_def_value="cds_globals.\\vdd! "; *) \vdd! ;
  electrical
     (* integer inh_conn_prop_name="vss";
        integer inh_conn_def_value="cds_globals.\\vss! "; *) \vss! ;

// INSTANCE PARAMETERS:
  parameter real tr=0.2n from (0:1m);            // risetime (for defaults)
  parameter real txdel=4*tr;                     // time midrange til output X
  parameter real ttol=tr/4;                      // time tolerance of crossing
// scaled input/output levels/thresholds (0 maps to Vref, 1 maps to Vsup):
  parameter real vthi=1/1.5 from (0:1);      // frac. for high tresh (def=2/3)
  parameter real vtlo=vthi/2 from (0:vthi);  // frac. for low tresh (def=1/3)
  parameter real vtol=(vthi-vtlo)/10 from (0:(vthi-vtlo)/4]; // frac. for vtol

// LOCAL VARIABLES:
  reg Dreg;                // output register
  reg Xin;                 // Tx control registers
  real Kin;                // input relative to supply range
  real txdig;              // tx in timescale units
  real vtlox,vthix;        // thresholds for transition to X state
  
//============================================================================
  initial begin
    txdig=txdel/1n;        // digital delay midlevel to X  (ASSUMES TIMESCALE)
    Dreg=(Kin>vthi)? 1'b1 : (Kin<vtlo)? 1'b0 : 1'bx;  // initial level
    Xin=0;                 // initially not in X delay region.
    vtlox=vtlo+2*vtol;     // lo-to-x threshold point
    vthix=vthi-2*vtol;     // hi-to-x threshold point
  end

// Relative input level (maps input to range of 0=vref, 1=vsup):
  analog  Kin = V(Ain,\vss! )/max(V(\vdd! ,\vss! ),1m);
  
// Convert analog signal to high/low and X/notX:
  always @(above(Kin-vthi,ttol,vtol))
      begin Dreg=1; Xin=0; end                   // analog XtoH
  always @(above(vtlo-Kin,ttol,vtol))
      begin Dreg=0; Xin=0; end                   // analog XtoL
  always @(above(vthix-Kin,ttol,vtol))
      if (Kin<vthi && Dreg!==1'bx) Xin=1;        // analog HtoX
  always @(above(Kin-vtlox,ttol,vtol))
      if (Kin>vtlo && Dreg!==1'bx) Xin=1;        // analog LtoX
// Wait for txdel before driving output to X:
  always @(posedge(Xin)) begin :GoToX            // input changed to X
    #(txdig)                                     // wait for X time delay
    if (Kin>vtlo && Kin<vthi) Dreg=1'bx;         // goto X if still between
    else Xin=0;                                  // else clear the X flag
  end
  always @(negedge(Xin)) disable GoToX;          // cancel out-to-X on Xin=0
  assign  Dout=Dreg;                             // assign register to output
endmodule
