[SOLVED] What is a proper way to model Xtal in KiCad?

I would like to model the following crystal oscillator in KiCad:

A model for 2N3904 transistor can be easily found online. However I don’t know how to model Y1. In LTspice I’m using an “xtal” component with following parameters to do this (funny enough that it’s called “Capacitor” in the dialog):

xtal model ltspice

Naturally I could just replace Y1 with an equivalent circuit but I would like to keep the schematic the way it is. After all it can be used for other purposes (BOM, PCB, etc).

Is it possible? I’m using KiCad 5.1.6. The project can be downloaded here.

1 Like

Hi,

You could build subcircuit model

  • The following is the instance card:

xqexample 1 2 vdivide

  • The following are the subcircuit definition cards:

.subckt vdivide 1 2

C1p 1 2 2.5pF
L1s 1 3 2.5H
C2s 3 4 0.01pF
R1s 4 2 640
.ends

image

Thanks for a quick reply, @Roland_W . However I still can’t model the given circuit. I placed the model you’ve provided to xtal.lib file. Afterwards this file was chosen for Y1 in Edit Spice Model… -> Model dialog:

When I execute the simulator I get the following output:

Circuit: KiCad schematic
Background thread stopped with timeout = 0
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000
Warning: singular matrix:  check nodes xqexample.3 and xqexample.3
Note: Starting dynamic gmin stepping
Trying gmin =   1.0000E-03 Note: One successful gmin step
Trying gmin =   1.0000E-04 Note: One successful gmin step
Trying gmin =   1.0000E-05 Note: One successful gmin step
Trying gmin =   1.0000E-06 Note: One successful gmin step
Trying gmin =   1.0000E-07 Note: One successful gmin step
Trying gmin =   1.0000E-08 Note: One successful gmin step
Trying gmin =   1.0000E-09 Note: One successful gmin step
Trying gmin =   1.0000E-10 Note: One successful gmin step
Trying gmin =   1.0000E-11 Note: One successful gmin step
Trying gmin =   1.0000E-12 Note: One successful gmin step
Trying gmin =   1.0000E-12 Note: One successful gmin step
Warning: singular matrix:  check nodes nc_01 and nc_01
Warning: Dynamic gmin stepping failed
Note: Starting source stepping
Supplies reduced to   0.0000% Warning: singular matrix:  check nodes nc_01 and nc_01
Trying gmin =   1.0000E-02 Note: One successful gmin step
Trying gmin =   1.0000E-03 Note: One successful gmin step
Trying gmin =   1.0000E-04 Note: One successful gmin step
Trying gmin =   1.0000E-05 Note: One successful gmin step
Trying gmin =   1.0000E-06 Note: One successful gmin step
Trying gmin =   1.0000E-07 Note: One successful gmin step
Trying gmin =   1.0000E-08 Note: One successful gmin step
Trying gmin =   1.0000E-09 Note: One successful gmin step
Trying gmin =   1.0000E-10 Note: One successful gmin step
Trying gmin =   1.0000E-11 Note: One successful gmin step
Trying gmin =   1.0000E-12 Note: One successful gmin step
Note: One successful source step
Supplies reduced to   0.1000% Warning: singular matrix:  check nodes nc_01 and nc_01
Supplies reduced to   0.0000% Warning: singular matrix:  check nodes nc_01 and nc_01
Warning: source stepping failed
Transient solution failed -
Last Node Voltages
------------------
Node                                   Last Voltage        Previous Iter
----                                   ------------        -------------
1                                                 0                    0
2                                                 0                    0
xqexample.3                                       0                    0
xqexample.4                                       0                    0
net-_c2-pad2_                          -1.10915e-55                    0
net-_c2-pad1_                           5.04157e-55                    0
net-_c1-pad1_                           5.37463e-55                    0
+12v                                    5.37463e-55                    0
xy1.3                                   5.04157e-55                    0
xy1.4                                             0                    0
nc_01                                             0                    0
l.xy1.l1s#branch                                  0                    0
l.xqexample.l1s#branch                            0                    0
doAnalyses: iteration limit reached
run simulation(s) aborted

It looks like this is the source of a problem:

Warning: singular matrix:  check nodes xqexample.3 and xqexample.3

Any ideas what it could mean? Or maybe I just did something wrong?

UPD: I decided to remove C4 and SIG from the schematic just to make sure these going nowhere connections don’t upset SPICE. This didn’t help much.

In the cases of the modeling that could be a Capacitor C1p - there no DC current path, some simulation could have a problem.

Add a Resistor at the beginning of the subcircuit
R1p 1 2 100Meg

@Roland_W thank you a lot for your help. Now the model starts but unfortunately the circuit doesn’t oscillate. After a while I realized that the voltage at +12V source is zero:

Despite the fact that it supposed to be modeled as a constant voltage source:

Thus I’ve added a VSOURCE to the schematic. The voltage is OK now but the circuit still doesn’t oscillate. I’m pretty sure that it should work because I’ve built it before and because it oscillates in LTspice just fine. A little piece of advice would be much appreciated.

UPD: The latest version of the project can be found here.

OK, by comparing voltage levels in different parts of the circuit and by using a little brute force I realized that the problem was with the pin numbers of 2N3904:

Now the circuit works as expected:

The frequency looks about right, I measured 4.761 MHz using cursors. I must say though, the UI of KiCad in regard of simulation needs a little improvement.

2 Likes

I’ve been trying to think of ways to best handle this. You think a simple text message next to the dropdown box for BJT would’ve been helpful? Something like this in the red box, which is a generic note followed by the SPICE netlist order pulled from the ngspice manual for the model type selected (in this example, a BJT):

At least it’s right there for you to see instead of having to look up the ngspice manual to cross-reference the correct ordering. Maybe also move the “Alternate node sequence” setting up top near the selection and the note??? Or do you have another idea to help notify the user that part pin numbers don’t match SPICE netlist sequences and they likely need to be shuffled around? Just trying to brainstorm here.

Hi @Ste and thank you for the attention to this issue!

The text message would be fine. I would even tell that the red box is an overkill. However I find the text you’ve given in the example a little confusing, because it doesn’t really explain what I supposed to do (as a regular user, that is not really into SPICE simulation). Something more like “If necessary, enter pin numbers in the order collector -> base -> emitter -> substrate (optional) in the Alternate node sequence, in case it differs from the default (1 2 3 4)” would be better. Ideally KiCad could do all this automatically, since it has all necessary information. But I realize that it might be not that simple to implement.

Sorry for the confusion. The red box was meant to just highlight for you where the changes are from what’s there currently. It wasn’t intended to also be there in a real setting.

How so? There’s no way to automatically know which pin is which on an arbitrary transistor part package. You mean all built-in KiCad symbols/packages should be updated manually to pre-define the Spice_Node_Sequence field?

Oh, OK. I thought that KiCad knows that Q1 on the schematic is not just “something” but a transistor and that pin 3 is a collector, etc. I didn’t realize that maybe it’s not the case.

Correct, it does assume Qs are BJTs by default, but you can override that. I just checked a bunch of the built-in NPN symbols, and many of them have the pin names defined as C, B, and E. If we are to assume all symbols are (and will be) consistent with this, then I can see a way to auto-order the pins for SPICE. The thing with this is there can exist corner cases where the assumption might fail: dual-packages, using subcircuits instead of models, etc. When “Alternate node sequence” is unchecked, maybe instead of applying a one-to-one mapping it tries to do an auto-detect based on pin-name instead? Maybe also throw an error if it encounters something violating the pin naming assumption? Do you think this is a good idea?

Thanks for the feedback. I don’t want to hijack this thread, but wanted your opinion since your first encounter with shuffling the pins around is still fresh in your mind.

1 Like

I think it’s a great idea. Maybe in this case KiCad could also show the user what pin order is used by default. For instance, when “Alternate node sequence” is not checked, the corresponding field could be inactive (gray) and filled automatically. I also believe that the originally proposed note regarding collector - base - emitter pin order is worth keeping.

1 Like