Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Discrepancy in gm for MOSFETs with Multiplier > 1

102 views
Skip to first unread message

Christos Toitos

unread,
Dec 20, 2024, 6:04:04 AM12/20/24
to xyce-users
Hi everyone,

I’ve observed a discrepancy in gm values between Xyce and Spectre when simulating MOSFETs with a multiplier > 1. For a multiplier of 1, the gm values align, but they diverge as the multiplier increases.

Does the Xyce team know about this issue? If so, are there plans to address it in future updates?

Cheers,
Christos

Thomas Russo

unread,
Dec 20, 2024, 11:27:59 AM12/20/24
to xyce-users
Which MOSFET models, specifically?

Multiplicity in Xyce is handled mostly by multiplying all current contributions by M right when they're loaded into the RHS vector, and in most cases of Verilog-A models, it's had to be hacked in to the Verilog-A source by the Xyce team because the model developers have assumed that multiplicity is handled by the simulator.

It is very likely that this is the reason for your discrepancy, because the output variables lie gm or cgs haven't been hacked to be multiplied by the multiplicity factor.

Are your discrepancies strictly off by a factor of "m"?  Or are they very much different than that?

Christos Toitos

unread,
Jan 14, 2025, 9:06:18 AMJan 14
to xyce-users
I am using the xfab xt018 MOSFET models and have observed discrepancies in the simulation results between a commercial simulator and Xyce. 

For gm, the results match when m = 1, but for m = 2, the Xyce value is off by a factor of 2. Here are the results:

| m      | commercial |   xyce         |
| ------   | ------------------- |---------          |
|  1     |  471.44uS      | 471.44uN |
|  2     |  926.66uS      | 463.32uN |

For Cgs, Xyce results are significantly different from the commercial simulator, and they do not scale with m. In contrast, the commercial simulator shows scaling with m. Here are the values:

| ------   | -----------          |------------------|
|  1     |  -1.05fF          | -361.66aN |
|  2     |  -2.02fF          | -361.64aN |

Thomas Russo

unread,
Jan 14, 2025, 6:47:42 PMJan 14
to xyce-users
So, obviously the not-scaling-with-m is exactly what I mentioned.

The Cgs issue is quite another thing.

There are only a few MOSFET devices in Xyce that have a CGS output variable, and some are known to have broken output variable issues related to capacitors.  As I recall, the BSIM-SOI 4.6.1 model (Xyce level 70 MOSFET) had some sort of issue with gate capacitances that was not present in the 4.5.0 version.  So we were forced to include 4.5.0 as a second option (level 70450 MOSFET in Xyce).  If your PDK is using that model as the level 70 MOSFET, that could possibly explain the gross error in CGS.

Without knowing precisely which of Xyce's supported MOSFET models are in use in your circuit, I can't say much more than that.

The actual models present in your circuit are printed at the top of Xyce's console output under the "Device Count Summary" heading.  What does it say regarding M devices?

Christos Toitos

unread,
Jan 15, 2025, 3:38:15 AMJan 15
to xyce-users
I am using the BSIM4 v4.7 model for M devices.

Thomas Russo

unread,
Jan 15, 2025, 11:56:46 AMJan 15
to xyce-users
Ah.  That narrows it down considerably.  The BSIM4 models are not derived from Verilog-A, they're manually ported over from very old SPICE C code. 

Most of those old SPICE conversions were done prior to the implementation of output variables in Xyce, and it looks on brief inspection like the output variable in Xyce is being set from a different internal variable than the one in the original SPICE code.  As I'm reading it, it looks like SPICE outputs the "Gm" internal variable for the operating point output, but Xyce is storing its internal "gm" variable to be output when "GM" is requested.  The "gm" version of the variable is the value of Gm scaled by the number of fingers in both Xyce and SPICE.

Is your MOSFET using an "nf" value other than 1.0?  If so, do the commercial simulator and Xyce differ by a factor of nf when M=1?

That might be a fairly easy fix for the Xyce team if that is the case.

Thomas Russo

unread,
Jan 15, 2025, 12:09:28 PMJan 15
to xyce-users
No, I'm wrong here --- I was misreading the SPICE code (easy to do, it's kind of hard to read sometimes).  SPICE outputs the same "gm" variable that Xyce does.  Except when asked for operating point values it scales by m before outputting (looking at the b4v7ask.c file of SPICE) .

So that accounts for the factor of m, but not the other discrepancy.  Sorry for the noise.

Thomas Russo

unread,
Jan 15, 2025, 12:27:50 PMJan 15
to xyce-users
One other thing --- I looked over the history of the Xyce code and find that when "gm" output was originally written in Xyce (back in 2016), an effort was made to compare it to  a transconductance computed as dIds/dVgs  by finite difference, and it was found to have been correct in the test cases run (for M=1, of course).   So diagnosing precisely why it is so different from your commercial simulator (other than the factor of m, which is obvious) might be quite difficult without more specifics of the circuit and parameters involved.

Thomas Russo

unread,
Jan 15, 2025, 1:55:43 PMJan 15
to xyce-users
On the other hand (sorry for this), your *real* discrepancies are in CGS, not gm, and I was digging for the wrong thing.   Your GM differences are clearly only a factor of m, it's CGS that's really off.

Xyce and SPICE handle capacitance terms differently, and lots of SPICE code has to be tweaked severely when porting from SPICE C code to Xyce C++ code.  This time I think that maybe SPICE and Xyce really are outputting different variables for CGS.   Xyce is outputting its CAPcgsb variable (a capacitance), which is sort of kind of derived from the code that SPICE uses to compute gcgsb (a conductance) from cgsb and cgso, but SPICE is outputting cgsb directly.  If I'm reading it correctly.   That *could* account for the extreme difference between Xyce and the commercial code for CGS. 

I think Xyce is just loading the wrong variable for outputting CGS.

Thomas Russo

unread,
Jan 15, 2025, 5:32:16 PMJan 15
to xyce-users
As a super quick test to this theory about cgsb being the right variable to use for CGS as opposed to Xyce's CAPcgsb, I tried just substituting that and doing a totally trivial comparison between Xyce and ngspice on the netlist "test1.cir" from the Xyce_Regression suite, modified to print cgs for both ngspice and Xyce.  I found that with no modification the codes were grossly different across the dc sweep.  Simply changing the code to store cgsb instead of CAPcgsb didn't fix it, though, because cgsb was always zero across the DC sweep. 

I then looked at how SPICE and Xyce set the "ChargeComputationNeeded" boolean and found that Xyce disables it for DC sweeps, but SPICE enables it if the circuit mode is "MODEDCTRANCURVE".

Tweaking Xyce's BSIM4v7 code to add "dcsweepFlag" to the list of states that enable ChargeComputationNeeded *AND* changing the output variable storage to cgsb instead brought Xyce's CGS in agreement with ngspice's.

So  I think the code for Xyce is being overly restrictive of when ChargeComputationNeeded is set and *also* is incorrectly saving the wrong variable for CGS.

I do not know how badly other things will break if ChargeComputationNeeded is set this way, though.  Something for the team to look into with all that extra time they have (not).

Thomas Russo

unread,
Jan 15, 2025, 5:34:18 PMJan 15
to xyce-users
When I say I used the "test1.cir" netlist, I really mean "the test1.cir netlist from the BSIM4_v4p7 test directory" as there are many "test1.cir" files.

Christos Toitos

unread,
Jan 16, 2025, 11:07:03 AMJan 16
to xyce-users
As I mentioned earlier, the gm (transconductance) is correct for m = 1, but it is not being properly scaled with m. 
For my testing, I created a simple circuit and ran it through both the commercial simulator and Xyce. Below is the netlist for the test circuit:

**.subckt ztest_xyce_discrepancies vdd_1v8_i gnd_i vout1 vout2
*.ipin vdd_1v8_i
*.ipin gnd_i
*.opin vout1
*.opin vout2

XM1 vout1 vout1 gnd_i net1 ne L=0.18u W=1u nf=1 m=1 par1=1
R1 vdd_1v8_i vout1 1k m=1

XM2 vout2 vout2 gnd_i net2 ne L=0.18u W=1u nf=1 m=2 par1=2
R2 vdd_1v8_i vout2 1k m=1
**.ends
.end

Regarding the gm scaling issue, I'm a bit confused about the solution.

As I understand it, the solution for Cgs involves adding the dcsweepFlag to the list of states that trigger ChargeComputationNeeded. Additionally, the output variable storage should be changed to cgsb instead of using Xyce's default CGS. However, setting the ChargeComputationNeeded flag may introduce other issues that we need to consider.

Regards,
Christos

Thomas Russo

unread,
Jan 16, 2025, 11:18:53 AMJan 16
to xyce-users
Yes, that about sums it up.  I found a code change that makes Xyce print the right answers, but the Xyce team will have to take it from here and see if making that change is OK and doesn't impact anything else.

I believe that the whole "ChargeComputationNeeded" thing was just a way of saving a few cycles on each device evaluation when capacitors aren't doing anything at DC, but the conditional in Xyce doesn't match the one in SPICE and there's work to be done on the Xyce end.

Maybe my investigations will help them get it done more quickly than if they had to devote the time to finding where the problem is.

Christos Toitos

unread,
Jan 16, 2025, 12:01:40 PMJan 16
to xyce-users
Apologies if this is a basic question, but as this is my first time interacting with the community, I wanted to check if there's anything specific I should do from my side to formally report the issue or contribute further?

Thomas Russo

unread,
Jan 16, 2025, 4:16:35 PMJan 16
to xyce-users
Formally reporting the issue is all that can be done here unless you care to hack on the code yourself to make it work for you.

I have already reported the issue on github:  https://github.com/Xyce/Xyce/issues/128

If you really need Xyce to work right now and produce the correct values of cgs, I can tell you which lines of code to change in what files (assuming you're building the code yourself from source on github), or you can look at the pull request I submitted to go with the issue.  Otherwise, one just has to wait for the team to do those changes and release another version.  That could be a while, based on the current patterns of code release (the team is very shorthanded and very busy with their internal requirements, and hasn't been able to release code often for the last year or so).

Christos Toitos

unread,
Jan 17, 2025, 3:08:50 AMJan 17
to xyce-users
Thank you for reporting the issue on GitHub. I would appreciate it if you could share which files you’ve modified to address the Cgs issue.
Additionally, I noticed that the fix for scaling gm hasn’t been addressed in an issue. Could you also provide some guidance on that as well?

Thomas Russo

unread,
Jan 17, 2025, 11:11:34 AMJan 17
to xyce-users
Well, the files changed and what was changed in them can be seen in the PR:  https://github.com/Xyce/Xyce/pull/129  .  Look on the "Files Changed" tab.

All that would have to be done to add multiplicity dependence would be to multiply cgsb and cgdb by the multiplicity when storing them (that storage is done in N_DEV_MOSFET_B4.C in two places, and the variable to multiply by is "numberParallel" in one of those places and "mi.numberParallel" in the other --- both spots should be obvious in the "files changed" tab of the PR).   I did not make that change in the PR just because there are many more output variables throughout Xyce that are wrong in this way and I didn't want to just fix one or two in a PR specifically aimed at fixing a real mistake.

Almost none of the devices in Xyce that support output variables have those variables scaled by multiplicity --- the few exceptions are those whose original authors took pains to implement multiplicity explicitly (PSP103 is one such model whose authors did it explicitly, and that might be the only one as far as I know).  Most do not, and all of those needed to be modified manually by the Xyce team to insert multiplicity in the first place.  Only some output variables are appropriate to scale by m, and one has to be careful to do it right.  I didn't want to open that can of worms.  Have to leave something fun for the Xyce team to track down themselves.
Reply all
Reply to author
Forward
0 new messages