Sensitivity analysis for inverter

226 views
Skip to first unread message

jsat...@usc.edu

unread,
Apr 24, 2019, 3:20:47 PM4/24/19
to xyce-users
I am very new to Xyce and the overall simulation world, and I am trying to use sensitivity analysis for an optimization problem.

I am trying to find the sensitivity of various parameters of the inverter wrt. to transistor widths.
I believe I have been able to perform sensitivity analysis of the output voltage named Vout in the netlist below.

However when i went to do the same to find the sensitivity of power i.e objfunc={P(vout)} , Xyce gives the following error

Error: Objective function does not contain a resolvable solution variable.

Also how would one find the sensitivity of the defined risepulse (as seen below in the attached netlist) of the inverter wrt to transistor widths ?



*CMOS INVERTER
** Analysis setup **
.PARAM ln=55n lp=55n
.param wp=200n
.param wn=100n
.tran 2ps 7ns
.print tran FORMAT=CSV PRECISION=16 {V(vout)} {v(1)} {P(MN1)} {P(MP1)} {P(VIN1)}
.measure tran risepulse trig V(VOUT) frac_max=0.1 + targ V(vout) frac_max=0.9
VDDdev     VDD    0    1.2V
VIN1  1    0  1.2V PULSE (1.2V 0V 1ns 10ps 10ps .25ns 0.5ns)
C2    VOUT  0  1e-15
MN1   VOUT  1 0 0 nfet l={ln} w={wn} ad='wn*160e-9' as='wn*160e-9' pd='2*wn+320e-9' ps='2*wn+320e-9' nrd='100e-9/wn' nrs='100e-9/wn' 
MP1   VOUT 1 VDD VDD pfet l={lp} w={wp} ad='wp*160e-9' as='wp*160e-9' pd='2*wp+320e-9' ps='2*wp+320e-9' nrd='100e-9/wp' nrs='100e-9/wp'

.print sens
* Sensitivity commands
.SENS objfunc={V(vout)} param=MN1:w,MP1:w
.options SENSITIVITY direct=1 adjoint=0



Any help would be greatly appreciated. 
Thanks in advance,
Arjun

xyce-users

unread,
Apr 24, 2019, 10:33:03 PM4/24/19
to xyce-users

Hi Arjun,

Unfortunately, the .SENS capability doesn't yet allow post-process variables such as power to be used as an objective function.  (The same thing is true of lead currents, which are similar).   

Objective functions work fine with solution variables and parameters (either specified via .param or .global_param).  Xyce, like most circuit simulators uses modified nodal analysis (MNA) which means that the solution vector is comprised of:

(1) voltages at every node
(2) currents thru devices where the current isn't a direct function of the junction voltage (like currents thru independent voltage sources).    So, this means that most current variables are NOT part of the solution vector.

So, most currents that can be requested on the .PRINT line are not solution variables, but are instead computed during the device load procedure.   For similar reasons, power isn't a solution variable either but is instead a post-process quantity.  (P = V*I). 

Supporting stuff like this in objective functions is already in our issue-tracker, so we plan to make this work eventually.  Making it work will require that lead currents and power calculations provide derivatives w.r.t. solution variables, and the relevant code hasn't been instrumented for this yet.

It may be possible to tackle this problem another way, however.  I'll see if I can make something work.  If I can, I'll post the netlist.

thanks,
the Xyce team








xyce-users

unread,
Apr 24, 2019, 11:23:27 PM4/24/19
to xyce-users

Hello again,

I just looked at this a bit more closely.  Computing P(vout) doesn't make much sense as power needs to be computed across a branch rather than a single node.  You could compute power at the node relative to ground, although I'm not sure if that is what you actually want.  To do something like this you could add the following:

Vmon vout vout2 0.0

change c2 to be connected from vout2 to ground:

C2    VOUT2  0  1e-15

and then:

objfunc={V(vout)*I(vmon)}

on the .SENS line.

This will make the objective function be equal to the power thru c2.  Sensitivity analysis will work for this objective, although I'm not sure it is quite what you were trying to achieve.  But at any rate, this is the sort of thing you can do to force the "objfunc" to be a power calculation.  Put a 0V voltage source in series with the branch that you want to compute power for, and then do  {I(vmon)*V} for your objective.

thanks,
the Xyce team



jsat...@usc.edu

unread,
Apr 25, 2019, 4:58:10 PM4/25/19
to xyce-users
Hello,

Thank you very much, I intended to mean objfunc=P{(MP1)} but I see your point. So this would automatically mean that I would not be able to perform sensitivity analysis of various circuit metrics like rise time using the trig targ functions in Xyce. 

Is there a way one perform the task, directly using Xyce?

I have been using external Python code to modify the circuit parameters differentially to calculate the gradients needed for optimization externally, but I was requested to try using .SENS ... Ergo the attempt. 

Also if this is not possible at this time, I was wondering if there is a way for the user to know the step size used in evaluating the gradients by .SENS? 
eg. in the netlist line where I am requesting the gradient 

.SENS objfunc={V(vout)} param=MN1:w,MP1:w

is there a way I could know the value of $\delta w$ for MN1 and MP1. The reason is then I might be able to use that  $\delta w$ for evaluating gradient using python for quantities that Xyce cannot produce for me?

Thank you very much in advance,
Arjun

xyce-users

unread,
Apr 25, 2019, 5:38:30 PM4/25/19
to xyce-users
Hi Arjun,

The .SENS capability computes derivatives analytically.   So, it doesn't use a delta as part of the computation, and there wouldn't be a meaningful delta to output.  In general, .SENS derivatives should be more accurate than finite difference derivatives, which is part of the advantage of using them.  The other advantage is speed, especially if you have a lot of sensitivities to compute.

Regarding things like trig and targ, yes, .SENS was developed independently of the development of .MEASURE in Xyce, so they aren't connected to each other in the source code.  That's a planned enhancement, but as there are many different variants of .measure it may take a while to fully support it.  Getting the value of a .measure is pretty easy, of course, but getting its derivatives (which are needed for the chain rule used by .sens) can be more challenging, depending on the specific .measure. 

In the meantime it is possible to use .sens to get the sensitivity of the equivalent of trig/targ and other .measures.  You just have to do some analytical post-processing of the SENS output.   I don't have time to get into that at the moment, but I'll post something later.

thanks,
the Xyce team

Mathieu COUSTANS

unread,
May 24, 2023, 4:48:58 PM5/24/23
to xyce-users
Dear Xyce team,

Just wondering if the two modules , .SENS and .MEASURE were connected in some releases ?
Or if some post processing function would be available for a cross point timing for example .MEASURE TRAN start_r WHEN V(x)='Value' TD='0' RISE=1 ?

Thanks,
Mathieu

xyce-users

unread,
Jun 5, 2023, 4:50:19 PM6/5/23
to xyce-users
My apologies for not answering earlier.

Currently, the .SENS and .MEASURE capabilities in Xyce are separate, so you cannot directly compute a sensitivity with respect to a .MEASURE output.   

The two sections of code were written at completely different times, by different people, so they've never been linked.  However, we are aware that linking them would be desirable for some users and we hope to make this happen.  We have an issue in our internal issue tracker related to this.

thanks,
Eric

Jin Yan

unread,
Jun 16, 2023, 6:58:06 PM6/16/23
to xyce-users
Hi Xyce team,

I'm also interested in performing the sensitivity analysis of delay w.r.t. transistor width. If this is not yet a feature supported in Xyce, is there any workaround? Based on one of the previous comments on this thread which is also quoted below, looks like this is something doable. Hope you can give me some suggestion how to move forward.

"In the meantime it is possible to use .sens to get the sensitivity of the equivalent of trig/targ and other .measures.  You just have to do some analytical post-processing of the SENS output.   I don't have time to get into that at the moment, but I'll post something later."

Thanks,
Jin

Mathieu COUSTANS

unread,
Jun 17, 2023, 7:03:20 AM6/17/23
to xyce-users
Thanks a lot Eric for the feedback,

Is there a way contribute in making this feature ?

Which source files handle these two feature ?

Thanks,
Mathieu 

--
You received this message because you are subscribed to a topic in the Google Groups "xyce-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/xyce-users/d3NoBeYnYGg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to xyce-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/xyce-users/b18ebc7f-f680-49d3-9202-ca02a7cbf6adn%40googlegroups.com.
--
Best regards,
                  Dr. Mathieu COUSTANS

//////////////////////////////////////////////////////////////////////////////

Mobile : +41 78 943 89 95

Mobile : +41 78 943 89 95

Sony Advanced Visual Sensing AG - Lead Integrated Circuit Innovation Engineer
IEEE Switzerland Section Treasurer
IEEE Solid State Circuit Society Switzerland Chapter Secretary.
IEEE Reviewer Transaction on Circuit and System I & II
IEEE Reviewer Journal of Solid State Circuit
IEEE Reviewer Solid State Circuit Letter

Sent from my iphone no mechanical keyboard close, so please excuse the touchscreen spelling

xyce-users

unread,
Jun 19, 2023, 7:31:40 PM6/19/23
to xyce-users
Hello Jin,

Sorry I didn't post anything about this earlier.   If you are interested in delay, there are a few different things you could try.

One approach is to use a "generalized Elmore delay" formula.  I used this approach in this paper:

You can download the PDF from here:

See section 4 and equations 16-17.

Another, completely different approach can be found  (mostly an experiment on my part) in the Xyce regression test suite, in the subdirectory Xyce_Regression/Netlists/SENS.  The specific circuit to look at is inverter_event.cir.


thanks,
Eric

Eric Keiter

unread,
Jun 19, 2023, 9:07:07 PM6/19/23
to xyce-users

Hello Mathieu,

Other people from outside of Sandia have hacked on the sensitivity code, so in theory it can be done.  But, we are restricted when it comes to accepting code changes from outside the lab.

However, if interested, the .MEASURE functions mostly sit in the Xyce/src/IOInterfacePKG/Output directory.  Most types of .MEASURE get their own class/C file.

The .SENS code sits in a few places.  For historical reasons, the original code  (which handled DC adjoint and DC direct sensitivities) sits in the nonlinear solver directory.  Xyce/src/NonlinearSolverPKG, in files such as N_NLS_Sensitivity.C and N_NLS_SensitivityResiduals.C.

For transient (direct and adjoint)  the code is in several places.  The sensitivity classes and functions in the NLS directory are still used for transient, but there are also functions in each of the time integration method classes. Those are in the Xyce/src/TimeIntegrationPKG directory, in files like N_TIA_OneStep.C (for trapezoid) and N_TIA_Gear12.C for Gear's method.  Transient adjoint is weird enough (as it needs to perform a reverse time integration) that a lot of its management happens in the N_ANP_Tranisent.C file, which is in the Xyce/src/AnalysisPKG directory.

There is also direct and adjoint sensitivities for AC, and nearly all the code for that type of analysis is in the N_ANP_AC.C file, in the Xyce/src/AnalysisPKG directory.

The biggest issue with connecting .MEASURE to .SENS is that .MEASURE will have to provide partial derivatives to complete the chain rule derivative computed by .SENS.  Currently, .MEASURE only computes the function, and doesn't compute any derivatives.  And, of course, there are many measures, and some of them are not differentiable.  Also, some of them are "event based" measures, which is more complex.   We have a paper on event-based objectives here:   https://ieeexplore.ieee.org/document/8203773

Unfortunately, the stuff from that paper hasn't made its way into Xyce yet.   So there is that as well.

thanks,
Eric

Jin Yan

unread,
Jun 23, 2023, 5:45:16 PM6/23/23
to xyce-users
Hi Eric,

Thanks for sharing these materials. I took a look at the inverter_event.cir in the regression test, and it looks like you tried to calculate the sensitivities for nmos:TOXE and pmos:TOXE. But you have instantiated multiplier inverters, why does this work without specifying which nmos and which pmos?
.SENS objfunc={v(eventTime)} param=nmos:TOXE,pmos:TOXE

I tried to map this example to SKY130 PDK, but I got a bunch of errors complaining about the BSIM version is too old. Is this technology depedent?

Thanks,
Jin

Thomas Russo

unread,
Jun 26, 2023, 6:10:40 PM6/26/23
to xyce-users
The parameters "nmos:TOXE" and "pmos:TOXE" mean "the TOXE parameter associated with the .model statement named nmos" and "the TOXE parameter associated with the .model statement named pmos," not to parameters of a specific device instance.  In this circuit, all nmos and pmos  transistors use one or the other model card (the model cards  are found in the include files in the directory with the netlist), and thus all share the same model parameters --- and the .SENS line computes the sensitivity of the entire circuit to these two parameters.  If one were interested only in the sensitivity of a single device instance's parameter, one would have to have a unique model card for that instance instead of a shared one, and the specify the parameter from *that* model card.

As for your question about the messages about BSIM versions, Xyce supports only a handful of specific BSIM4 versions (via the combination of LEVEL and VERSION parameters in the model cards), and if the model card specifies a VERSION older than the oldest Xyce supports, you get a *warning* (not an error) that it will be using the oldest it has instead of the one requested.  Xyce supports only versions 4.6.1, 4.7.0, and 4.8.2.  As I understand it, there are some model cards in the SKY130 PDK that specify 4.5.0 and earlier versions of BSIM4, which are not supported in Xyce --- in this case, Xyce is using BSIM 4.6.1 instead.  You can most likely ignore the warnings as there should be sufficient backward compatibility in those early versions, but Xyce warns you about what it's doing so that you know that it's made that substitution. 

BSIM4 is the only BSIM device in Xyce 7.6 that supports multiple versions via the LEVEL/VERSION combination technique.  Until that was added last year, Xyce only supported one version of every LEVEL of MOSFET, and that is still the case for all the other BSIM devices other than BSIM4 --- if there are multiple versions supported in Xyce, they're done as separate LEVELs in the .model card, and the "VERSION" parameter is ignored.

Jin Yan

unread,
Jun 26, 2023, 6:33:02 PM6/26/23
to xyce-users
Hi Thomas,

Thanks a lot for getting back to me so quickly!

I'm particularly interested in running sensitivity analysis of delay w.r.t. transistor width of each transistor to do transistor sizing for better performance. Based on what you explained in your reply, I need to use a separate model card for each transistor, correct? Is there any command in Xyce that allows me to duplicate the model card for many times instead of I manually copy past content from the PDK?

As for the BSIM4 issue, you're right that what I saw is just warning instead of error.

Thanks,
Jin

Thomas Russo

unread,
Jun 26, 2023, 11:32:14 PM6/26/23
to xyce-users
Transistor size, unlike parameters like TOXE, is determined by instance parameters such as L and W.  *THESE* parameters belong to the instance, not a model card, and are not shared by multiple instances.  So you can use the syntax "<instance>:<instance parameter>" to specify them in the list of sensitivity parameters.  So, for the inverter_event circuit, you could use things like "Xinv1:Mp1:L" for the length of the MP1 transistor in the Xinv1 subcircuit.

The thing to remember is that in Xyce, just as in SPICE3F5 on which it was originally patterned, parameters for devices are either instance or model parameters, and unlike HSPICE are not all legal in both contexts.  If you consult the Reference Guide you'll find each device type's legal instance and model parameters enumerated.   There are some parameters that are legal in both contexts, but that's because Xyce has special code for each of those exceptions that allows a model card to specify a default value for every instance, but allows instances to override that default.  In the case of the BSIM4, L and W are NOT legal in both instance and model and are always specified on the instance line.

Jin Yan

unread,
Jun 28, 2023, 6:43:30 PM6/28/23
to xyce-users
Hi Thomas,

It makes sense now. Thanks a lot for your detailed explaination.
As you can see below, I modified the inverter_event.cir in order to use the device model from SKY130. If I ran transient simulation only, it can finish successfully and the eventTime is able to capture the time when Vo crosses 0.9V. However, when I try to run transient simulation together with sensitivity analysis, the simulation was aborted and there was no clear error message showing where the error is. What could be wrong here? Is there any way to printout more error message? I tried to increase the debuglevel option, but it didn't help.

.lib /usr/local/google/home/yanji/sky130A/libs.tech/ngspice/sky130.lib.spice tt
.options timeint method=gear debuglevel=1 reltol=1.0e-6 abstol=1.0e-6
.options device temp=25 debuglevel=1

* --- Voltage Sources ---
vdd   supply  0 dc 1.8
VIN1 vi 0 PWL(0S 0V  100ps 0V 300ps 1.8V )

* --- Inverter Subcircuit ---
.subckt inverter vin vout vdd gnd
Xn1 gnd vin vout gnd sky130_fd_pr__nfet_01v8 w=650000u l=150000u
Xp1 vdd vin vout vdd sky130_fd_pr__pfet_01v8_hvt w=1e+06u l=150000u
.ends

* --- Inverter ---
Xinv1  vi 1 supply 0 inverter
Xinv2  1 2 supply 0 inverter
Xinv3  2 3 supply 0 inverter
Xinv4  3 4 supply 0 inverter
Xinv5  4 vo supply 0 inverter

*********************************************************************************
* big conductance, no delay (for BEFORE the event)
.param RnoDelay=1.0e-4
.param GnoDelay={1/RnoDelay}
.param logGnoDelay={log(GnoDelay)}

* small conductance, large delay (for AFTER the event)
.param RbigDelay=1.0e+7
.param GbigDelay={1/RbigDelay}
.param logGbigDelay={log(GbigDelay)}

.param scale={ ( logGnoDelay - logGbigDelay )/2 }
.param Vthresh = 0.9
.param Vwidth = 0.001
.param widthScale = {1/Vwidth}

.func smoothG (V) {10**( scale*(1+tanh( (V-Vthresh)*widthScale)) + logGbigDelay)}

.param CeventParam=1.0e-6

.param RCnoConst={CeventParam*RnoDelay}
.param RCbigConst={CeventParam*RbigDelay}

* event circuit
Bevent  timeNode 0 V={time}
BeventR timeNode eventTime I={ smoothG(v(vo)) *(v(timeNode)-v(eventTime)) }
Cevent eventTime 0 {CeventParam}
*********************************************************************************

* --- Transient Analysis ---
.tran 2ps 1ns

.print tran v(vi) v(1) v(2) v(3) v(4) v(vo)
+ v(timeNode)
+ v(eventTime)

.SENS objfunc={v(eventTime)} param=Xinv1:Xp1:msky130_fd_pr__pfet_01v8_hvt:W,Xinv1:Xn1:msky130_fd_pr__nfet_01v8:W

.options SENSITIVITY adjoint=1 direct=0  adjointTimePoints=1ns

.print TRANADJOINT  

* this is here to fool xyce verify.
.print sens

.end

Thomas Russo

unread,
Jun 28, 2023, 6:54:54 PM6/28/23
to xyce-users
Unfortunately I can't help you with why it might have aborted the simulation, and will have to leave that to the Xyce team proper to answer (I'm writing in my retirement as an interested observer and supporter of the project).

You should know, though, that "debuglevel" does absolutely nothing unless you have compiled Xyce with special options, and then it dumps *enormous* amounts of detailed internal information as it runs --- it is going to be like trying to drink from a fire hose.  It is not meant for netlist debugging by users, but for code debugging by developers.

There are less intense ways to see what's going on during a run by compiling Xyce with "verbose" options (with the autoconf build, one adds things like "--enable-verbose_time", "--enable-verbose_nonlinear" at configure time, and there are equivalent tricks in the CMake build), but even these can be overwhelming and possibly not informative.  It'll show you things like detailed information about the nonlinear solver's progress, what it is doing in transient, etc.  If you know what to look for you might *glean* more information about a failure from it, but it won't be as simple as "more error messages."

When you say it aborts with no "clear" error message, do you mean it aborts with no error message at all, or the message isn't clear?  I ask because there are a lot of error messages that Xyce produces that mean something to the person who wrote the code, but don't always clearly explain it to someone else.

Jin Yan

unread,
Jun 28, 2023, 7:13:08 PM6/28/23
to xyce-users
That's so nice of you. Really appreciate your help in this open-source community!

After digging into the log file, I found that the errors are hidden in many warning messages. It complains about the effective channel width is less than 0. I also copied the error message below. 

Netlist error in file
 /usr/local/google/home/yanji/sky130A/libs.tech/ngspice/corners/../../../libs.ref/sky130_fd_pr/spice/sky130_fd_pr__pfet_01v8_hvt__tt.pm3.spice
 at or near line 33
 Device instance XINV1:XP1:MSKY130_FD_PR__PFET_01V8_HVT: mosfet
 XINV1:XP1:MSKY130_FD_PR__PFET_01V8_HVT model
 XINV1:XP1:SKY130_FD_PR__PFET_01V8_HVT__MODEL.80  Effective channel width <= 0

Netlist error in file
 /usr/local/google/home/yanji/sky130A/libs.tech/ngspice/corners/../../../libs.ref/sky130_fd_pr/spice/sky130_fd_pr__nfet_01v8__tt.pm3.spice
 at or near line 31
 Device instance XINV1:XN1:MSKY130_FD_PR__NFET_01V8: mosfet
 XINV1:XN1:MSKY130_FD_PR__NFET_01V8 model
 XINV1:XN1:SKY130_FD_PR__NFET_01V8__MODEL.89  Effective channel width <= 0

Based on the following message, Xyce tries to calculate the sensitivity numerically, so my guess is it tries to change the width to a illegal value during this numerical sensitivity calculation. Any other thoughts?
Netlist warning: At least one specified sensitivity parameter lacks an
 analytic derivative, so numerical derivatives will be used for that parameter
 for sensitivity calculations.  This also means that the full linear system
 must be evaluated at every step.  The default behavior is to only re-evaluate
 the nonlinear portions of the problem for efficiency.  The simulation may be
 slower as a result.

Thanks,
Jin

Thomas Russo

unread,
Jun 28, 2023, 9:19:36 PM6/28/23
to xyce-users
Again, I'll have to leave it to the Xyce team to get you detailed assistance on what sensitivity is doing under the hood, but the error message you're receiving is from one of the BSIM devices, I'm guessing BSIM4.

The effective channel width is computed from the actual width and length from the instance line folded in with several model parameters.  The exact formula can be found in the "updateTemperature" function of the specific device that's actually getting invoked (if it's the BSIM4, that depends on what VERSION is in the model card).  Your speculation that perhaps a bad value of width is being selected during computation of numerical derivatives seems likely --- the value of width is probably fine, but when it's folded together with the other parameters to get the effective channel width it's getting something negative.  There may be a way to specify the step size used in finite differences to stay away from that case, but Eric will have to answer that.

In some of the newer BSIM devices (BSIM4SOI, BSIM-CMG, BSIM6) that condition trips a warning instead of a fatal error, but in all the older models (BSIM3, BSIM4, and B3SOI) it's a fatal error.  I just looked, and ng-spice's code for the BSIM4 also throws a fatal error in this condition. Xyce's older BSIM devices are based on the SPICE implementation, so that's why it's implemented as a fatal error.

Jin Yan

unread,
Jun 29, 2023, 12:13:39 AM6/29/23
to Thomas Russo, xyce-users
Hi Thomas,

Again, thanks a lot for helping me debug this issue even though this is no longer your job:)
I just checked the effective channel width calculation in the BSIM4 manual and it involves with quite a number of model parameters as you mentioned. While waiting for the Xyce team to give me further guidance, I will play with some other W/L to see if this error shows up all the time or not.

Thanks,
Jin

--
You received this message because you are subscribed to a topic in the Google Groups "xyce-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/xyce-users/d3NoBeYnYGg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to xyce-users+...@googlegroups.com.

xyce-users

unread,
Jul 15, 2023, 5:22:50 PM7/15/23
to xyce-users

Hi Jin,

Sorry it took us a long time to respond.  For sensitivity analysis, I'm usually the person who responds, but I was on vacation.

Anyway, I think I've managed to follow the recent discussions that I missed.   

As you and Tom speculated, the BSIM4 has to do a numerical derivative to perform sensitivity analysis.  At a high level, sensitivity analysis obtains derivatives via a chain rule calculation (apologies if I said this already in an earlier post):

dO/dp = dO/dx * dx/dF * dF/dp

where "O" is a scalar objective function, "p" is a scalar parameter, "x" is the solution vector and "F" is the residual vector that is minimized by the Newton solver.  In practice "F" is mostly KCL equations and "x" is mostly voltage node values.   dO/dp is the scalar sensitivity that you want.

The transient and AC versions of this are a bit more complicated, but they still follow this general pattern.

Ideally, all 3 of the above terms are determined analytically.  If "O" is specified as an expression (typical), then dO/dx can be computed analytically by traversing the abstract syntax tree setup by our expression library.   dx/dF is basically the inverse of the Jacobian matrix used by the Newton solver, which is analytical.  So that is always analytical as well.

The dF/dp term, however, is something that involves device models and only some of them are instrumented to provide an analytical dF/dp.  Many device models have been set up to provide analytical forms of dF/dp, usually via automatic differentiation.   All the models that were generated using the ADMS model compiler have this feature, for example.   The BSIM4, unfortunately, was written by hand and doesn't have an analytical dFdp set up.  There is an entry in our internal issue-tracker to do this, but it hasn't gotten done yet.

Fortunately, Xyce is smart enough to  compute dFdp numerically if it isn't available analytically.  The delta that is used for this calculation is very small, to ensure accuracy.   But the fact that it is small means that I'm surprised that you get the fatal errors that you are reporting;  the new value for "p", which is "p+delta_p" should still be very close to the original value, and that original value didn't trigger the error.  So it must be very close to that threshold for triggering the error.

However, setting that aside, we should probably change the fatal errors in the BSIM4 to warnings.  I think that is a good practice anyway and (as Tom mentioned) that has already been done in some of the other BSIM models.  So, I'll enter an issue in our internal issue tracker to make that happen (assuming there isn't an issue about this in there already).  Unlike the analytical dF/dp issue, this is easy to do.

Would you be able to send us a netlist that exhibits the error?  

thanks,
Eric

xyce-users

unread,
Jul 15, 2023, 5:24:36 PM7/15/23
to xyce-users
It looks like you posted the netlist already in a previous comment, so ignore my final question.

cheers,
Eric

Jin Yan

unread,
Jul 17, 2023, 12:23:08 PM7/17/23
to xyce-users
Hi Eric,

Thanks a lot for looking into this issue! I tried to set the transistor width to be different values but this error continues to show up, so there is no update on my side. Maybe you will have a better sense of what's going on after enabling higher debug options.

Thanks,
Jin

xyce-users

unread,
Feb 27, 2024, 6:58:46 PMFeb 27
to xyce-users
Hello Jin,

I know it has been a really long time since you posted about this issue.    In July, I looked into it briefly, but didn't have time to fully diagnose or fix the problem.

Yesterday, I took another look at it, and it turns out the issue was easy to fix.  Sorry I didn't fix it more quickly!  Possibly, you have moved on and don't need the fix anymore.  However,  for what it is worth, it is fixed now.  Here is an explanation.

When using the Sky130 PDK (which you are using), the command ".option scale=1.0e-6" is used.  This means that the L,W parameters on MOSFET devices such as the BSIM4 are scaled by a factor of 1.0e-6.  So, rather than setting L=0.65e-6, the user would instead set L=0.65 with the understanding that it would actually mean L=0.65e-6.

Unfortunately, this particular feature (which is relatively new to Xyce) potentially messes up any code that tweaks parameters behind the scenes.  And, for your circuit, the BSIM4 device (as it doesn't have analytical sensitivities implemented) much perform a device-level finite difference.  In doing this device-level finite difference, it needed to take into account the "option scale" command properly.  But, unfortunately it did not.  So, every time the finite difference code was called, this parameter got scaled and re-scaled over and over.  This resulted in the whole calculation getting messed up.

This was very easy to fix in the code, and I fixed it today.  So, it will go into our local git repo today and will get merged over to the public git repo the next time we do a public merge.    Also, this fix will be in subsequent Xyce releases such as Xyce 7.9.

thanks!
Eric

Jin Yan

unread,
Feb 27, 2024, 7:45:12 PMFeb 27
to xyce-users
Hi Eric,

Thanks a lot for the fix! My workaround was to calculate the sensitivity by running simulations with different width and then doing finite difference which is very tedious and time-consuming. Now I've moved on to a different topic, but once the fix is merged, I will definitely try it out.

Thanks,
Jin

Reply all
Reply to author
Forward
0 new messages