//======================================================================================
//======================================================================================
// Filename: PSP102_nqs_macrodefs.include
//======================================================================================
//======================================================================================
//
//  (c) Copyright 2007, All Rights Reserved, NXP Semiconductors
//
//
//  Version: 102.1, April 2007 (Simkit 2.5)
//
//======================================================================================
//======================================================================================
//
// Further information can be found in the file readme.txt
//

//////////////////////////////////////////
//
// Macros used in PSP-NQS
//
//////////////////////////////////////////

// Function to calculate bulk charge from surface potential
`define PhiToQb(phi,Qb_tmp) \
if (abs(phi) <= margin) \
    Qb_tmp     = -0.70710678 * phi * Gf * (1.0 - `oneSixth * phi * (1.0 - `oneSixth * phi)); \
else begin \
    `expl((-phi), temp) \
    Qb_tmp     =  Gf * sqrt(temp + phi - 1.0); \
    if (phi > margin) \
        Qb_tmp     = -Qb_tmp; \
end 


// Function used in fq-macro
`define PhiTod2Qis(xphi,d2Qis) \
if (abs(xphi) <= margin) begin \
    Qb_tmp     = -0.70710678 * xphi * Gf * (1.0 - `oneSixth * xphi * (1.0 - `oneSixth * xphi)); \
    dQbs       = -0.70710678 * Gf * (1.0 - `oneThird * xphi * (1.0 - 0.25 * xphi)); \
    d2Qis      = -0.235702 * Gf * (1.0 - 0.5 * xphi); \
end else begin \
    `expl((-xphi),temp) \
    Qb_tmp     =  Gf * sqrt(temp + xphi - 1.0); \
    if (xphi > margin) \
        Qb_tmp     = -Qb_tmp; \
    dQbs       =  0.5 * Gf2 * (1.0 - temp) / Qb_tmp; \
    d2Qis      = (dQbs * dQbs - 0.5 * Gf * Gf) / Qb_tmp + dQbs; \
end



// Function used in QiToPhi
`define sps(sp, xg) \
if (abs(xg) <= marginp) begin \
    sp         = xg / a_factrp; \
end else begin \
    if (xg < -marginp) begin \
        NQS_yg     =  -xg; \
        NQS_z      =  1.25 * NQS_yg / a_factrp; \
        NQS_eta    =  (NQS_z + 10.0 - sqrt((NQS_z - 6.0) * (NQS_z - 6.0) + 64.0)) * 0.5; \
        NQS_a      =  (NQS_yg - NQS_eta) * (NQS_yg - NQS_eta) + Gp2 * (NQS_eta + 1.0); \
        NQS_c      =  2.0 * (NQS_yg - NQS_eta) - Gp2; \
        NQS_tau    =  ln(NQS_a / Gp2) - NQS_eta; \
        `sigma(NQS_a, NQS_c, NQS_tau, NQS_eta, NQS_y0) \
        `expl(NQS_y0, NQS_D0) \
        NQS_xi     =  1.0 - Gp2 * NQS_D0 * 0.5;  \
        NQS_p      =  2.0 * (NQS_yg - NQS_y0) + Gp2 * (NQS_D0 - 1.0); \
        NQS_q      =  (NQS_yg - NQS_y0) * (NQS_yg - NQS_y0) + Gp2 * (NQS_y0 + 1.0 - NQS_D0); \
        NQS_temp   =  NQS_p * NQS_p - 4.0 * NQS_xi * NQS_q; \
        NQS_w      =  2.0 * NQS_q / (NQS_p + sqrt(NQS_temp)); \
        sp         =  -(NQS_y0 + NQS_w); \
    end else begin \
        NQS_xg1    =  1.0 / ( 1.25 + 7.32464877560822e-01 * Gp); \
        NQS_A_fac  =  (1.25 * a_factrp * NQS_xg1 - 1.0) * NQS_xg1; \
        NQS_xbar   =  xg / a_factrp * (1.0 + NQS_A_fac * xg); \
        `expl(-NQS_xbar, NQS_temp)   \
        NQS_w      =  1.0 - NQS_temp; \
        NQS_x0     =  xg + Gp2 * 0.5 - Gp * sqrt(xg + Gp2 * 0.25 - NQS_w); \
        `expl((-NQS_x0), NQS_D0) \
        NQS_xi     =  1.0 - Gp2 * 0.5 * NQS_D0; \
        NQS_p      =  2.0 * (xg - NQS_x0) + Gp2 * (1.0 - NQS_D0); \
        NQS_q      =  (xg - NQS_x0) * (xg - NQS_x0) - Gp2 * (NQS_x0 - 1.0 + NQS_D0); \
        NQS_temp   =  NQS_p * NQS_p - 4.0 * NQS_xi * NQS_q; \
        NQS_u      =  2.0 * NQS_q / (NQS_p + sqrt(NQS_temp)); \
        sp         =  NQS_x0 + NQS_u; \
    end \
end


// Function to calculate surface potential from inversion charge
`define QiToPhi(Qi,xg,xphi) \
    temp       =  Qi / pd + xg; \
    `sps(xphi,temp)

// Calculation of fk
`define fq(Qi,xg,dQy,d2Qy,fk) \
    `QiToPhi(Qi, xg, xphi) \
    `PhiTod2Qis(xphi, d2Qis) \
    dQis       =  pd - dQbs; \
    dQis_1     =  1.0 / dQis; \
    fQi        =  Qi * dQis_1 - 1.0; \
    dfQi       =  (1.0 - Qi * d2Qis * dQis_1 * dQis_1) * dQis_1; \
    fk0        =  dfQi * dQy * dQy + fQi * d2Qy; \
    dpsy2      =  dQy * dQy * dQis_1 * dQis_1; \
    zsat       =  thesat2 * dpsy2; \
    if (CHNL_TYPE == `PMOS) \
        zsat       =  zsat / (1.0 + thesat1 * dps); \
    temp       =  sqrt(1.0 + 2.0 * zsat); \
    Fvsat      =  2.0 / (1.0 + temp); \
    temp1      =  d2Qy - dpsy2 * d2Qis; \
    fk         =  Fvsat * (fk0 - zsat * fQi * temp1 * Fvsat / temp);


// Interpolation of surface potential along channel
`define Phiy(y) \
    x_m + H * (1.0 - sqrt(1.0 - 2.0 * dps / H * ((y) - ym))) * inv_phit1
