/// <summary>
        /// Updates the charges and capacitances..
        /// </summary>
        /// <param name="mode">The mode.</param>
        /// <param name="vgs">The gate-source voltage.</param>
        /// <param name="vds">The drain-source voltage.</param>
        /// <param name="vbs">The bulk-source voltage.</param>
        /// <param name="von">The threshold voltage.</param>
        /// <param name="vdsat">The saturation voltage.</param>
        /// <param name="mp">The model parameters.</param>
        /// <param name="tp">The temperature-dependent properties.</param>
        public void Update(double mode, double vgs, double vds, double vbs, double von, double vdsat,
                           ModelParameters mp,
                           TemperatureProperties tp)
        {
            var    vbd = vbs - vds;
            var    vgd = vgs - vds;
            double arg, sarg, sargsw;

            /*
             * now we do the hard part of the bulk-drain and bulk-source
             * diode - we evaluate the non-linear capacitance and
             * charge
             *
             * the basic equations are not hard, but the implementation
             * is somewhat long in an attempt to avoid log/exponential
             * evaluations
             */
            /*
             *  charge storage elements
             *
             *.. bulk-drain and bulk-source depletion capacitances
             */

            // Can't bypass the diode capacitance calculations
            if (!tp.Cbs.Equals(0.0) || !tp.CbsSidewall.Equals(0.0))
            {
                if (vbs < tp.TempDepCap)
                {
                    arg = 1 - vbs / tp.TempBulkPotential;

                    /*
                     * the following block looks somewhat long and messy,
                     * but since most users use the default grading
                     * coefficients of .5, and sqrt is MUCH faster than an
                     * Math.Exp(Math.Log()) we use this special case code to buy time.
                     * (as much as 10% of total job time!)
                     */
                    if (mp.BulkJunctionBotGradingCoefficient.Equals(mp.BulkJunctionSideGradingCoefficient))
                    {
                        if (mp.BulkJunctionBotGradingCoefficient.Equals(0.5))
                        {
                            sarg = sargsw = 1 / Math.Sqrt(arg);
                        }
                        else
                        {
                            sarg = sargsw =
                                Math.Exp(-mp.BulkJunctionBotGradingCoefficient *
                                         Math.Log(arg));
                        }
                    }
                    else
                    {
                        if (mp.BulkJunctionBotGradingCoefficient.Equals(0.5))
                        {
                            sarg = 1 / Math.Sqrt(arg);
                        }
                        else
                        {
                            sarg = Math.Exp(-mp.BulkJunctionBotGradingCoefficient *
                                            Math.Log(arg));
                        }
                        if (mp.BulkJunctionSideGradingCoefficient.Equals(0.5))
                        {
                            sargsw = 1 / Math.Sqrt(arg);
                        }
                        else
                        {
                            sargsw = Math.Exp(-mp.BulkJunctionSideGradingCoefficient *
                                              Math.Log(arg));
                        }
                    }
                    Qbs = tp.TempBulkPotential * (tp.Cbs *
                                                  (1 - arg * sarg) / (1 - mp.BulkJunctionBotGradingCoefficient)
                                                  + tp.CbsSidewall *
                                                  (1 - arg * sargsw) /
                                                  (1 - mp.BulkJunctionSideGradingCoefficient));
                    Cbs = tp.Cbs * sarg + tp.CbsSidewall * sargsw;
                }
                else
                {
                    Qbs = tp.F4s + vbs * (tp.F2s + vbs * (tp.F3s / 2));
                    Cbs = tp.F2s + tp.F3s * vbs;
                }
            }
            else
            {
                Qbs = 0;
                Cbs = 0;
            }

            // can't bypass the diode capacitance calculations
            if (!tp.Cbd.Equals(0.0) || !tp.CbdSidewall.Equals(0.0))
            {
                if (vbd < tp.TempDepCap)
                {
                    arg = 1 - vbd / tp.TempBulkPotential;

                    /*
                     * the following block looks somewhat long and messy,
                     * but since most users use the default grading
                     * coefficients of .5, and sqrt is MUCH faster than an
                     * Math.Exp(Math.Log()) we use this special case code to buy time.
                     * (as much as 10% of total job time!)
                     */
                    if (mp.BulkJunctionBotGradingCoefficient.Equals(0.5) &&
                        mp.BulkJunctionSideGradingCoefficient.Equals(0.5))
                    {
                        sarg = sargsw = 1 / Math.Sqrt(arg);
                    }
                    else
                    {
                        if (mp.BulkJunctionBotGradingCoefficient == .5)
                        {
                            sarg = 1 / Math.Sqrt(arg);
                        }
                        else
                        {
                            sarg = Math.Exp(-mp.BulkJunctionBotGradingCoefficient *
                                            Math.Log(arg));
                        }
                        if (mp.BulkJunctionSideGradingCoefficient == .5)
                        {
                            sargsw = 1 / Math.Sqrt(arg);
                        }
                        else
                        {
                            sargsw = Math.Exp(-mp.BulkJunctionSideGradingCoefficient *
                                              Math.Log(arg));
                        }
                    }
                    Qbd = tp.TempBulkPotential * (tp.Cbd *
                                                  (1 - arg * sarg)
                                                  / (1 - mp.BulkJunctionBotGradingCoefficient)
                                                  + tp.CbdSidewall *
                                                  (1 - arg * sargsw)
                                                  / (1 - mp.BulkJunctionSideGradingCoefficient));
                    Cbd = tp.Cbd * sarg + tp.CbdSidewall * sargsw;
                }
                else
                {
                    Qbd = tp.F4d + vbd * (tp.F2d + vbd * tp.F3d / 2);
                    Cbd = tp.F2d + vbd * tp.F3d;
                }
            }
            else
            {
                Qbd = 0;
                Cbd = 0;
            }

            // Calculate Meyer capacitances
            double cgs, cgd, cgb;

            if (mode > 0)
            {
                Transistor.MeyerCharges(vgs, vgd, von, vdsat, out cgs, out cgd, out cgb, tp.TempPhi, tp.OxideCap);
            }
            else
            {
                Transistor.MeyerCharges(vgd, vgs, von, vdsat, out cgd, out cgs, out cgb, tp.TempPhi, tp.OxideCap);
            }
            Cgs = cgs;
            Cgd = cgd;
            Cgb = cgb;
        }
Beispiel #2
0
        /// <summary>
        /// Calculates the charges and capacitances for the specified voltages.
        /// </summary>
        /// <param name="behavior">The biasing behavior.</param>
        /// <param name="mp">The model parameters.</param>
        public void Calculate(IMosfetBiasingBehavior behavior, ModelParameters mp)
        {
            var tp  = behavior.Properties;
            var vgs = behavior.Vgs;
            var vds = behavior.Vds;
            var vbs = behavior.Vbs;

            /*
             * Now we do the hard part of the bulk-drain and bulk-source
             * diode - we evaluate the non-linear capacitance and
             * charge.
             *
             * The basic equations are not hard, but the implementation
             * is somewhat long in an attempt to avoid log/exponential
             * evaluations.
             */

            // Bulk-source depletion capacitances
            {
                /* can't bypass the diode capacitance calculations */
                if (tp.Cbs != 0 || tp.CbsSidewall != 0)
                {
                    if (vbs < tp.TempDepCap)
                    {
                        double arg = 1 - vbs / tp.TempBulkPotential;
                        double sarg, sargsw;

                        /*
                         * the following block looks somewhat long and messy,
                         * but since most users use the default grading
                         * coefficients of .5, and sqrt is MUCH faster than an
                         * Math.Exp(Math.Log()) we use this special case code to buy time.
                         * (as much as 10% of total job time!)
                         */
                        if (mp.BulkJunctionBotGradingCoefficient == mp.BulkJunctionSideGradingCoefficient)
                        {
                            if (mp.BulkJunctionBotGradingCoefficient == .5)
                            {
                                sarg = sargsw = 1 / Math.Sqrt(arg);
                            }
                            else
                            {
                                sarg = sargsw = Math.Exp(-mp.BulkJunctionBotGradingCoefficient * Math.Log(arg));
                            }
                        }
                        else
                        {
                            if (mp.BulkJunctionBotGradingCoefficient == .5)
                            {
                                sarg = 1 / Math.Sqrt(arg);
                            }
                            else
                            {
                                sarg = Math.Exp(-mp.BulkJunctionBotGradingCoefficient * Math.Log(arg));
                            }
                            if (mp.BulkJunctionSideGradingCoefficient == .5)
                            {
                                sargsw = 1 / Math.Sqrt(arg);
                            }
                            else
                            {
                                sargsw = Math.Exp(-mp.BulkJunctionSideGradingCoefficient * Math.Log(arg));
                            }
                        }
                        Qbs = tp.TempBulkPotential * (tp.Cbs *
                                                      (1 - arg * sarg) / (1 - mp.BulkJunctionBotGradingCoefficient)
                                                      + tp.CbsSidewall *
                                                      (1 - arg * sargsw) /
                                                      (1 - mp.BulkJunctionSideGradingCoefficient));
                        Cbs = tp.Cbs * sarg + tp.CbsSidewall * sargsw;
                    }
                    else
                    {
                        Qbs = tp.F4s + vbs * (tp.F2s + vbs * (tp.F3s / 2));
                        Cbs = tp.F2s + tp.F3s * vbs;
                    }
                }
                else
                {
                    Qbs = 0;
                    Cbs = 0;
                }
            }

            // Bulk-drain depletion capacitances
            {
                var vbd = vbs - vds;
                if (tp.Cbd != 0 || tp.CbdSidewall != 0)
                {
                    if (vbd < tp.TempDepCap)
                    {
                        double arg = 1 - vbd / tp.TempBulkPotential;
                        double sarg, sargsw;

                        /*
                         * the following block looks somewhat long and messy,
                         * but since most users use the default grading
                         * coefficients of .5, and sqrt is MUCH faster than an
                         * Math.Exp(Math.Log()) we use this special case code to buy time.
                         * (as much as 10% of total job time!)
                         */
                        if (mp.BulkJunctionBotGradingCoefficient == .5 && mp.BulkJunctionSideGradingCoefficient == .5)
                        {
                            sarg = sargsw = 1 / Math.Sqrt(arg);
                        }
                        else
                        {
                            if (mp.BulkJunctionBotGradingCoefficient == .5)
                            {
                                sarg = 1 / Math.Sqrt(arg);
                            }
                            else
                            {
                                sarg = Math.Exp(-mp.BulkJunctionBotGradingCoefficient * Math.Log(arg));
                            }
                            if (mp.BulkJunctionSideGradingCoefficient == .5)
                            {
                                sargsw = 1 / Math.Sqrt(arg);
                            }
                            else
                            {
                                sargsw = Math.Exp(-mp.BulkJunctionSideGradingCoefficient * Math.Log(arg));
                            }
                        }
                        Qbd = tp.TempBulkPotential * (tp.Cbd *
                                                      (1 - arg * sarg)
                                                      / (1 - mp.BulkJunctionBotGradingCoefficient)
                                                      + tp.CbdSidewall *
                                                      (1 - arg * sargsw)
                                                      / (1 - mp.BulkJunctionSideGradingCoefficient));
                        Cbd = tp.Cbd * sarg +
                              tp.CbdSidewall * sargsw;
                    }
                    else
                    {
                        Qbd = tp.F4d + vbd * (tp.F2d + vbd * tp.F3d / 2);
                        Cbd = tp.F2d + vbd * tp.F3d;
                    }
                }
                else
                {
                    Qbd = 0;
                    Cbd = 0;
                }
            }

            // Meyer capacitance calculation
            {
                /*
                 * new cmeyer - this just evaluates at the current time,
                 * expects you to remember values from previous time
                 * returns 1/2 of non-constant portion of capacitance
                 * you must add in the other half from previous time
                 * and the constant part
                 */
                double cgs, cgd, cgb;
                if (behavior.Mode > 0)
                {
                    Transistor.MeyerCharges(vgs, vgs - vds, mp.MosfetType * behavior.Von, mp.MosfetType * behavior.Vdsat, out cgs, out cgd, out cgb, tp.TempPhi, tp.OxideCap);
                }
                else
                {
                    Transistor.MeyerCharges(vgs - vds, vgs, mp.MosfetType * behavior.Von, mp.MosfetType * behavior.Vdsat, out cgd, out cgs, out cgb, tp.TempPhi, tp.OxideCap);
                }
                Cgs = cgs;
                Cgd = cgd;
                Cgb = cgb;
            }
        }