226 views

Skip to first unread message

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

** 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

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

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

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

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

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

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

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

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. MathieuCOUSTANS//////////////////////////////////////////////////////////////////////////////

Mobile : +41 78 943 89 95

Mobile : +41 78 943 89 95Sony 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

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

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

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

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.

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

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.

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

.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

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.

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

/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

/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.

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

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.

Jun 29, 2023, 12:13:39 AM6/29/23

to Thomas Russo, xyce-users

Hi Thomas,

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.

To view this discussion on the web visit https://groups.google.com/d/msgid/xyce-users/95774420-bb7a-4e75-92f2-40fb5c8266aen%40googlegroups.com.

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

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

Eric

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

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

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