4
\$\begingroup\$

I am currently trying to figure out how to add tolerance to my LM4040, ZVP2160, and 2N3904 components.

I'm attempting a Monte Carlo analysis and use the {mc(value,tolerance)} for the value of my resistors, but obviously changing the value breaks the custom part. I'm wondering if there is a way to modify VTO = -1.5 to something like VTO = mc(-1.5,.01) for example.

Is it even possible to add tolerance to custom components in LTspice?

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Yea, you can do that, but all your parts with the same model name will have the same value for each monte carlo run. So for example if you did that for VTO on a 2N7002 MOSFET, all your 2N7002s will have the same VTO on each run. If you need them to be independent of each other you’ll have to do something else. If you have only a few instances, the fastest way would be to give each its own .model statement so the mc() function could be evaluated independently for each MOSFET. Something like this: i.sstatic.net/Hrz97yOy.png \$\endgroup\$
    – Ste Kulov
    Commented Sep 5 at 18:33
  • 2
    \$\begingroup\$ @SteKulov Please post that as an answer \$\endgroup\$
    – Voltage Spike
    Commented Sep 5 at 19:59
  • \$\begingroup\$ @VoltageSpike Rereading the title, it sounds like they want to do it within .lib files. I'll have to put in some more research first before I can draft a good answer. \$\endgroup\$
    – Ste Kulov
    Commented Sep 6 at 3:30
  • 1
    \$\begingroup\$ That's fair, one thing to remember is comments can be deleted and are like post it notes, answers are not. The comment you posted looks good enough to be an answer. \$\endgroup\$
    – Voltage Spike
    Commented Sep 6 at 10:57

2 Answers 2

4
\$\begingroup\$

Im wondering if there is a way to modify VTO = -1.5 to something like VTO = mc(-1.5,.01) for example.

Yes, you can do this and it's pretty straightforward (especially using LTspice's ako keyword) if you only have one instance of each .model you want to use. The only thing you're missing in your statement are the curly braces around the mc() function.

However, an issue arises when you use multiple instances of the same .model. LTspice only evaluates the .model statement once per each simulation run. So if you had three MOSFETs, then all three would have identical VTOs for each run as shown below. Notice that all 3 plots are on top of each other.

single .model statement


If you need them independent of each other you have to do some more work. If you only have a few of the same device, you can manually define each with its own .model statement and unique name as shown below. Now they have their own unique VTOs.

multiple .model statements


But what if you have MANY instances and you need them to all be different? It would get pretty tedious crafting new .model statements for each instance. But we don't have to do that because there is a trick we can use which only takes a little bit of work upfront. If you know how LTspice works, .model statements are loaded/evaluated into the SPICE engine once on each run but each time you instantiate a .subckt (subcircuit) the netlist inside gets evaluated for each instance. We can use this fact to our advantage and embed our .model statement within a .subckt. The one disadvantage of doing this is the ako keyword breaks within a .subckt, so we have to copy/paste the entire .model statement manually and edit just the Vto= part.

embedding the .model into a .subckt


The last part of this trick (which was done above) requires you adjusting the NMOS symbols to expect a .subckt instead of a .model. You do this by CTRL+rightclick-ing the symbol and changing the "Prefix" field from MN (or whatever it is for your device) to X. You can do this once and copy/paste that symbol anywhere you need that device on your schematic.

changing the symbol prefix


Lastly, you mentioned in the title of the question something about .lib files. You can use the .subckt trick within external .lib files as well. You just have to make sure that the .model keyword that you want to use is in between the .subckt and .ends statements. If it's outside that scope then it will only get evaluated once like normal and won't generate unique values for each instance.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Wonderful answer. I wonder what would be an easy way to set the number of tries.. Just something like .step param i 1 10 1 with i being an irrelevant parameter? \$\endgroup\$
    – tobalt
    Commented Sep 6 at 11:10
  • \$\begingroup\$ @tobalt Yes, that’s exactly right. You just need a way to force multiple runs and that’s typically how it’s done. mc(x,y) is just a function that generates a random number with uniform distribution. There is also a gaussian built-in and you can make a custom worst-case function too. I actually never use the mc(x,y) one because I think the others are more useful. An article that explains these can be found here: analog.com/en/resources/technical-articles/… \$\endgroup\$
    – Ste Kulov
    Commented Sep 6 at 14:01
  • 1
    \$\begingroup\$ Random tolerance range sampling can be more useful if xou have many interconnected parts with tolerance and extreme behavior could arise from non extreme values (I guess, and I guess it would be very rare) \$\endgroup\$
    – tobalt
    Commented Sep 6 at 15:01
  • \$\begingroup\$ @tobalt Yea, agreed, but I still think the gaussian is more useful…at least for what I typically do. You’re right though that uniform does test all random combinations equally and makes the least assumptions about what statistical profile you may have on a part. \$\endgroup\$
    – Ste Kulov
    Commented Sep 6 at 18:59
  • 1
    \$\begingroup\$ No I meant that sampling the entire tolerance range (using any random sampler) could uncover extreme cases that you could miss if you only checked each part at its nominal+min+max value. \$\endgroup\$
    – tobalt
    Commented Sep 6 at 21:06
3
\$\begingroup\$

I assume you've already familiarized yourself with the MonteCarlo.asc file in the educational subdirectory of LTspice. So I won't belabor those details.

What I'll do is grab up a schematic I have -- it's a circuit that once triggered by a manual switch will continue to power a circuit for a specified period of time. (\$R_{_\text{DEVICE}}\$ is the circuit being powered.)

It uses a MOSFET device as part of the circuit. So I've modified my schematic to perform a Monte Carlo on \$V_{_\text{TO}}\$ of the BSS123. Note that I constructed my own MODEL statement and included the VTO parameter there, using a 5% tolerance around the typical value of \$1.6\:\text{V}\$.

enter image description here

You can see just how much variation in the circuit timing would be due to even that small amount of variation.

Hopefully, this shows you how. If you are using .SUBCKT/.ENDS models, the same thing applies. But you can also include parameters into these that can then be used with specific parts within the sub-circuit. It all just works fine.

(I didn't use resistor or capacitor tolerances here. This is just to demonstrate how to modify active device parameters. Not to exhibit this circuit, in particular. It's just an example to make a point.)

The device parameters for the BSS123 exist in the standard library file. But they may just as well have come from any library file you might include. You will need to write your own model statement, of course. But the ako: allows you to pull in all the library parameters that you don't want to vary. So it's really easy to vary only the parameters you want to modify.

added

Here's an example. It includes two separate current sources that help to show what's going on (should be only integer currents.) Meanwhile, I've set up the two BJTs to grab up (possibly) two different models for the purposes of showing the behavior of a differential amplifier (long-tailed pair.) This produces different models (sometimes) for the two different BJTs. So it can be used to show a range of behaviors.

enter image description here

\$\endgroup\$
5
  • 1
    \$\begingroup\$ For a circuit using several of the same type components, e.g. BSS123s, you'd have to call them BSS123A, BSS123B etc. and place a model card for each of them (with ako and mc), right? \$\endgroup\$
    – tobalt
    Commented Sep 6 at 6:11
  • \$\begingroup\$ @tobalt It I follow you, then LTspice has an idiosyncrasy. If you use numbers for the model names (1, 2, 3, ...) and then a STEP can be used to walk through any number of random models. It may be possible to use this fact with mc to get what you may be hinting at. Haven't tried it. I would need to think about the math needed to get integers out from it. \$\endgroup\$ Commented Sep 6 at 6:50
  • \$\begingroup\$ The point was having the interplay between (uncorrelated) tolerances be respected by the simulation. I.e. if there are two FETs, their Vto values will both deviate from the nominal, but deviate differently, so they cannot both be BSS123A, because that would make their Vto tolerance correlated due to being derived from the same model card with the same mc step. \$\endgroup\$
    – tobalt
    Commented Sep 6 at 8:39
  • \$\begingroup\$ @tobalt I believe I gathered that idea from your question. And I think there may be a way to force different selections, as random. As I wrote though, I've not yet tried to use the idea that still sits in my head. I may update later when I find out. \$\endgroup\$ Commented Sep 6 at 10:37
  • \$\begingroup\$ @tobalt I've added something along the lines my mind was moving. I'm not sure if it meets your hopes. But it was what I was thinking about when I was writing, earlier. Best wishes! \$\endgroup\$ Commented Sep 6 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.