# Howto debug ngspice error PPerror: syntax error during transient analysis

In an effort to better understand software and how my computer actually works I have been experimenting with simple electronic circuits.

I am working up to having three two bit registers (A, B, C) and a two bit ripple adder. The idea is to add A+B and put the result in C. Overflow handling is out of scope.

Being a newb I've built and rebuilt some of the building blocks on a breadboard and learned a tonne, but as the builds got more elaborate the prototyping time added up. Learning SPICE was next.

After wrestling with a few programs I ended up settling on KiCad which I quite like. I use KiCad to draw out circuits, generate a SPICE netlist, and from there I run ngspice 30 manually on the command line to test the circuit. .op analysis is great for my skill level but I'm trying to understand what flip flops to use and why.

In real life I prototyped a D Flip Flop but a lot of what I've read suggests that a JK is simpler and more versatile. I wanted to model a JK flip flop and that seems like a job for a .tran.

I have benefitted greatly from the ngspice manual (http://ngspice.sourceforge.net/docs/ngspice-30-manual.pdf) and the community but I'm stuck on getting a transient analysis to work the way I think it should work. Specifically the relationship between the .tran and the .print.

The current flip flop I have sketched out uses NOR logic to implement what I think is a JK Flip Flop (my designs might be incorrect). I'm less worried about the designs and more about understanding SPICE syntax.

My current netlist is as follows:

.title KiCad schematic
.model NPN npn (is=6.7e-15 bf=416.4 nf=1 vaf=74.03 ikf=0.06678 ise=6.7e-15 ne=1.259 br=0.7371 nr=1 rb=10 rc=1)
V2 /jk-flip-flop-1/K 0 dc 5
V3 /jk-flip-flop-1/J 0 dc 5
V4 /jk-flip-flop-1/CLK 0 dc 5
R28 /jk-flip-flop-1/not-and-3-k/NQ /jk-flip-flop-1/sr-latch-jk/sheet5C3630E6/AorB 10K
R29 /jk-flip-flop-1/NQ /jk-flip-flop-1/sr-latch-jk/sheet5C3630E6/AorB 10K
Q10 /jk-flip-flop-1/Q /jk-flip-flop-1/sr-latch-jk/sheet5C3630E6/AorB 0 NPN
R31 /jk-flip-flop-1/Q /jk-flip-flop-1/sr-latch-jk/sheet5C3630F6/AorB 10K
R32 /jk-flip-flop-1/not-and-3-j/NQ /jk-flip-flop-1/sr-latch-jk/sheet5C3630F6/AorB 10K
Q11 /jk-flip-flop-1/NQ /jk-flip-flop-1/sr-latch-jk/sheet5C3630F6/AorB 0 NPN
R41 /jk-flip-flop-1/and-3-j/nor-3-ga3/A /jk-flip-flop-1/and-3-j/nor-3-ga3/AorBorC 10K
R42 /jk-flip-flop-1/and-3-j/nor-3-ga3/B /jk-flip-flop-1/and-3-j/nor-3-ga3/AorBorC 10K
Q15 /jk-flip-flop-1/and-3-j/Q /jk-flip-flop-1/and-3-j/nor-3-ga3/AorBorC 0 NPN
R43 /jk-flip-flop-1/and-3-j/nor-3-ga3/C /jk-flip-flop-1/and-3-j/nor-3-ga3/AorBorC 10K
R45 /jk-flip-flop-1/NQ /jk-flip-flop-1/and-3-j/not-a-ga3/Qr 10K
Q16 /jk-flip-flop-1/and-3-j/nor-3-ga3/A /jk-flip-flop-1/and-3-j/not-a-ga3/Qr 0 NPN
R47 /jk-flip-flop-1/J /jk-flip-flop-1/and-3-j/not-b-ga3/Qr 10K
Q17 /jk-flip-flop-1/and-3-j/nor-3-ga3/B /jk-flip-flop-1/and-3-j/not-b-ga3/Qr 0 NPN
R49 /jk-flip-flop-1/CLK /jk-flip-flop-1/and-3-j/not-c-ga3/Qr 10K
Q18 /jk-flip-flop-1/and-3-j/nor-3-ga3/C /jk-flip-flop-1/and-3-j/not-c-ga3/Qr 0 NPN
R51 /jk-flip-flop-1/and-3-j/Q /jk-flip-flop-1/not-and-3-j/Qr 10K
Q19 /jk-flip-flop-1/not-and-3-j/NQ /jk-flip-flop-1/not-and-3-j/Qr 0 NPN
R53 /jk-flip-flop-1/and-3-k/nor-3-ga3/A /jk-flip-flop-1/and-3-k/nor-3-ga3/AorBorC 10K
R54 /jk-flip-flop-1/and-3-k/nor-3-ga3/B /jk-flip-flop-1/and-3-k/nor-3-ga3/AorBorC 10K
Q20 /jk-flip-flop-1/and-3-k/Q /jk-flip-flop-1/and-3-k/nor-3-ga3/AorBorC 0 NPN
R55 /jk-flip-flop-1/and-3-k/nor-3-ga3/C /jk-flip-flop-1/and-3-k/nor-3-ga3/AorBorC 10K
R57 /jk-flip-flop-1/CLK /jk-flip-flop-1/and-3-k/not-a-ga3/Qr 10K
Q21 /jk-flip-flop-1/and-3-k/nor-3-ga3/A /jk-flip-flop-1/and-3-k/not-a-ga3/Qr 0 NPN
R59 /jk-flip-flop-1/K /jk-flip-flop-1/and-3-k/not-b-ga3/Qr 10K
Q22 /jk-flip-flop-1/and-3-k/nor-3-ga3/B /jk-flip-flop-1/and-3-k/not-b-ga3/Qr 0 NPN
R61 /jk-flip-flop-1/Q /jk-flip-flop-1/and-3-k/not-c-ga3/Qr 10K
Q23 /jk-flip-flop-1/and-3-k/nor-3-ga3/C /jk-flip-flop-1/and-3-k/not-c-ga3/Qr 0 NPN
R63 /jk-flip-flop-1/and-3-k/Q /jk-flip-flop-1/not-and-3-k/Qr 10K
Q24 /jk-flip-flop-1/not-and-3-k/NQ /jk-flip-flop-1/not-and-3-k/Qr 0 NPN
.tran 0.1n 10n
.save v(/jk-flip-flop-1/q)
.print tran v(/jk-flip-flop-1/q)
.end


I realize I probably should not have K/J both high, but I'm looking to get any transient output. Making the analysis more elaborate can come later. I'm also assuming that I'm trying to read the voltage at the flip flop's Q output value but I might have butchered the syntax there.

The current output of the program looks like an .op output, but with an opaque seeming error: PPerror: syntax error

The full output is:

Circuit: KiCad schematic

Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

Initial Transient Solution
--------------------------

Node                                   Voltage
----                                   -------
/jk-flip-flop-1/k                            5
/jk-flip-flop-1/j                            5
/jk-flip-flop-1/clk                          5
/jk-flip-flop-1/not-and-3-k/nq      0.00495018
/jk-flip-flop-1/sr-latch-jk/sheet5c3630e6/aorb      0.00495018
/jk-flip-flop-1/nq                  0.00495018
/jk-flip-flop-1/q                   0.00495019
/jk-flip-flop-1/sr-latch-jk/sheet5c3630f6/aorb      0.00495019
/jk-flip-flop-1/not-and-3-j/nq      0.00495019
/jk-flip-flop-1/and-3-j/nor-3-ga3/a       0.0224665
/jk-flip-flop-1/and-3-j/nor-3-ga3/aorborc       0.0224665
/jk-flip-flop-1/and-3-j/nor-3-ga3/b       0.0224665
/jk-flip-flop-1/and-3-j/q           0.00712348
/jk-flip-flop-1/and-3-j/nor-3-ga3/c       0.0224665
/jk-flip-flop-1/and-3-j/not-a-ga3/qr      0.00495018
/jk-flip-flop-1/and-3-j/not-b-ga3/qr         0.66242
/jk-flip-flop-1/and-3-j/not-c-ga3/qr         0.66242
/jk-flip-flop-1/not-and-3-j/qr      0.00712348
/jk-flip-flop-1/and-3-k/nor-3-ga3/a       0.0224665
/jk-flip-flop-1/and-3-k/nor-3-ga3/aorborc       0.0224665
/jk-flip-flop-1/and-3-k/nor-3-ga3/b       0.0224665
/jk-flip-flop-1/and-3-k/q           0.00712331
/jk-flip-flop-1/and-3-k/nor-3-ga3/c       0.0224665
/jk-flip-flop-1/and-3-k/not-a-ga3/qr         0.66242
/jk-flip-flop-1/and-3-k/not-b-ga3/qr         0.66242
/jk-flip-flop-1/and-3-k/not-c-ga3/qr      0.00495019
/jk-flip-flop-1/not-and-3-k/qr      0.00712331
v4#branch                         -0.000867516
v3#branch                         -0.000433758
v2#branch                         -0.000433758

No. of Data Rows : 108
PPerror: syntax error

Total analysis time (seconds) = 0.00571

Total CPU time (seconds) = 0.040

Current dynamic memory usage = 0 bytes,
Dynamic memory limit = 8796093018071.918 MB.


The output makes sense to me from my understand of an .op analysis but I don't know how to make the .tran "go".

• The netlists are difficult to read, particularly when lots of elements/nodes are involved, and/or fluffy node names are used. It's probably the reason graphical interfaces have been build around them. Have you tried a more graphical approach? I admit my eyes get crossed easily when looking at the whole code. – a concerned citizen Jan 9 at 8:37

I have a hunch it has something to do with these lines.

.save v(/jk-flip-flop-1/q)
.print tran v(/jk-flip-flop-1/q)


I believe this post illustrates the issue: Re: Problems with nodes with slashes in their names.

NgSpice will parse the contents of v(...) for which it detects a '/' which translates to a division operator. This is a syntax error for the parser.

• You're right. I should not have assumed KiCad would generate safe names. Slashes (and dashes) won't work in the v(...) – Bennett Jan 9 at 12:31

In the ngspice git development branch pre-master I have uploaded a patch that allows commands like

.print tran v("/jk-flip-flop-1/q")


Enclosure of the node name in " is required convincing the parser that this is a string.

• i ended up writing a script that tokenizes and replaces the strings with base32 short codes. The long names get truncated in the transient output otherwise. – Bennett Feb 13 at 19:30