//======================================================================================
//======================================================================================
// Filename: PSP103_nqs_macrodefs.include
//======================================================================================
//======================================================================================
//
//  (c) Copyright notice
//
//  Since 2015 until today, PSP has been co-developed by NXP Semiconductors and
//  CEA-Leti. For this part of the model, each claim undivided ownership and copyrights
//  Since 2012 until 2015, PSP has been co-developed by NXP Semiconductors and
//  Delft University of Technology. For this part of the model, each claim undivided
//  ownership and copyrights
//  Until and including 2011, PSP has been co-developed by NXP Semiconductors and
//  Arizona State University. For this part of the model, NXP Semiconductors claims
//  undivided ownership and copyrights.
//
//
//  Version: 103.7.0 (PSP), 200.6.0 (JUNCAP), April 2019
//
//======================================================================================
//======================================================================================
//
// Further information can be found in the file releasenotesPSP103.txt
//

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

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

// Function used in fq-macro
`define PhiTod2Qis(xphi,d2Qis) \
    if (abs(xphi) <= margin_ac) begin \
        Qb_tmp     = -0.70710678 * xphi * Gf_ac * (1.0 - `oneSixth * xphi * (1.0 - `oneSixth * xphi)); \
        dQbs       = -0.70710678 * Gf_ac * (1.0 - `oneThird * xphi * (1.0 - 0.25 * xphi)); \
        d2Qis      = -0.235702 * Gf_ac * (1.0 - 0.5 * xphi); \
    end else begin \
        `expl((-xphi),temp) \
        Qb_tmp     =  Gf_ac * sqrt(temp + xphi - 1.0); \
        if (xphi > margin_ac) \
            Qb_tmp     = -Qb_tmp; \
        dQbs       =  0.5 * Gf_ac * Gf_ac * (1.0 - temp) / Qb_tmp; \
        d2Qis      = (dQbs * dQbs - 0.5 * Gf_ac * Gf_ac) / 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_nqs   =  thesat2 * dpsy2; \
    if (CHNL_TYPE == `PMOS) \
        zsat_nqs   =  zsat_nqs / (1.0 + thesat1_ac * dps_ac); \
    temp       =  sqrt(1.0 + 2.0 * zsat_nqs); \
    Fvsat      =  2.0 / (1.0 + temp); \
    temp1      =  d2Qy - dpsy2 * d2Qis; \
    fk         =  Fvsat * (fk0 - zsat_nqs * fQi * temp1 * Fvsat / temp);

// Interpolation of surface potential along channel
`define Phiy(y) \
    x_m_ac + H_ac * (1.0 - sqrt(1.0 - 2.0 * dps_ac / H_ac * ((y) - ym))) * inv_phit1
