Exemplo n.º 1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Frequency"/> class.
 /// </summary>
 /// <param name="context">The binding context.</param>
 /// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/> is <c>null</c>.</exception>
 public Frequency(IComponentBindingContext context)
     : base(context)
 {
     ModelParameters = context.ModelBehaviors.GetParameterSet <ModelParameters>();
     Behavior        = context.Behaviors.GetValue <IMosfetBiasingBehavior>();
     _complex        = context.GetState <IComplexSimulationState>();
     Variables       = new MosfetVariables <Complex>(context, _complex);
     _elements       = new ElementSet <Complex>(_complex.Solver, Variables.GetMatrixLocations(_complex.Map));
 }
Exemplo n.º 2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Frequency"/> class.
 /// </summary>
 /// <param name="context">The binding context.</param>
 /// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/> is <c>null</c>.</exception>
 public Frequency(IComponentBindingContext context)
     : base(context)
 {
     ModelParameters = context.ModelBehaviors.GetParameterSet <ModelParameters>();
     Behavior        = context.Behaviors.GetValue <IMosfetBiasingBehavior>();
     _complex        = context.GetState <IComplexSimulationState>();
     Variables       = new MosfetVariables <Complex>(Name, _complex, context.Nodes,
                                                     !ModelParameters.DrainResistance.Equals(0.0) || !ModelParameters.SheetResistance.Equals(0.0) && Behavior.Parameters.DrainSquares > 0,
                                                     !ModelParameters.SourceResistance.Equals(0.0) || !ModelParameters.SheetResistance.Equals(0.0) && Behavior.Parameters.SourceSquares > 0);
     _elements = new ElementSet <Complex>(_complex.Solver, Variables.GetMatrixLocations(_complex.Map));
 }
Exemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Time"/> class.
        /// </summary>
        /// <param name="context">The binding context.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/> is <c>null</c>.</exception>
        public Time(IComponentBindingContext context)
            : base(context)
        {
            context.ThrowIfNull(nameof(context));
            _time     = context.GetState <ITimeSimulationState>();
            _behavior = context.Behaviors.GetValue <IMosfetBiasingBehavior>();
            _mp       = context.ModelBehaviors.GetParameterSet <ModelParameters>();
            var method = context.GetState <IIntegrationMethod>();

            _vgs = new StateValue <double>(2); method.RegisterState(_vgs);
            _vds = new StateValue <double>(2); method.RegisterState(_vds);
            _vbs = new StateValue <double>(2); method.RegisterState(_vbs);
            _cgs = new StateValue <double>(2); method.RegisterState(_cgs);
            _cgd = new StateValue <double>(2); method.RegisterState(_cgd);
            _cgb = new StateValue <double>(2); method.RegisterState(_cgb);
            _qgs = method.CreateDerivative();
            _qgd = method.CreateDerivative();
            _qgb = method.CreateDerivative();
            _qbd = method.CreateDerivative();
            _qbs = method.CreateDerivative();
            _behavior.UpdateContributions += UpdateTime;
        }
Exemplo n.º 4
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;
            }
        }