Pwrs() function in SPICE model gives an error

I’ve got a 12AX7 (ECC83) vacuum tube SPICE model (see below) from Duncan’s Amp Pages (http://tdsl.duncanamps.com/dcigna/tubes/spice/12ax7a.inc) that I’ve tweaked slightly to use in KiCAD.

I changed 12AX7A to ECC83. It’s the same design, just different manufacturer model numbers, so that’s not a concern.

What concerns me is I also had to change pwrs(), signed power, to pwr(), unsigned power, to get it to work without throwing an error about an unknown function pwrs(). Since most vacuum tube designs work by varying a negative grid voltage (making it more or less negative, never positive) I’m assuming the “signed” part of “signed power” is important for the model to function correctly.

After searching the 'net, it seems that ngspice has a pwrs() function (or at least I found an old enhancement request asking for it) so I don’t understand the error.

My question is this: Is there a pwrs() function, maybe called something else, in ngspice that I’m not finding? If not, is there some other workaround? Or, is there a better model for a 12AX7/ECC83 that I should be using?

Here’s the original model, followed by my modified version with changes in bold:

.SUBCKT 12AX7A P G K
E1  2  0  VALUE={45+V(P,K)+95.43*V(G,K)}
R1  2  0  1.0K
Gp  P  K  VALUE={1.147E-6*(PWR(V(2),1.5)+PWRS(V(2),1.5))/2}
Cgk G  K  1.6P
Cgp G  P  1.7P
Cpk P  K  0.46P
.ENDS 12AX7A

.SUBCKT **ECC83** P G K
E1  2  0  VALUE={45+V(P,K)+95.43*V(G,K)}
R1  2  0  1.0K
Gp  P  K  VALUE={1.147E-6*(PWR(V(2),1.5)+**PWR**(V(2),1.5))/2}
Cgk G  K  1.6P
Cgp G  P  1.7P
Cpk P  K  0.46P
.ENDS **ECC83**

This is a snip from the ngspice manual, section 16.14.2:

You need to define your own PWRS(x,a) function using the syntax described to emulate PSpice’s native function. Or you can just use its definition in that one spot you need it.

ngspice's PSPICE compatibility mode implicitly defines, beside other things:

.func limit(x, a, b) { min(max(x, a), b) }
.func pwr(x, a) { pow(x, a) }
.func pwrs(x, a) { sgn(x) * pow(x, a) }
.func stp(x) { u(x) }

@Ste’s information above looks more correct and also matches what LTspice does (it’s also mentioned in a closed bug ticket). Maybe you should create a new ngspice bug ticket.

Thank you @Ste and @franzee. I appreciate your quick replies. I will look into the PSPICE compatibility mode. Unless it’s a default, I’m sure I did not have it set. And, thanks for the link to the ngspice manual. I’ve added it to my bookmarks.

I tried the instructions for adding set ngbehavior=ps to my .spiceinit file. I also tried calling it spice.rc as suggested. Neither worked. But, using SGN(V(2))*PWR(V(2),1.5)) in place of PWRS(V(2),1.5)) did the trick.

The reason for “Neither worked” may be that you have put .spiceinit into the wrong place. Please see http://ngspice.sourceforge.net/ngspice-eeschema.html for a shaort instruction.

I am trying to post a reply with what I have done and the fact that the results are the same, but I keep running up against: Sorry, new users can only mention 2 users in a post.

I have no idea why that is. I’m not @mentioning anyone. Perhaps it’s confused by something I’ve included? I put in my netlists and the commands I used to verify the init files.

Anybody know a way around this 2 users thing?

I copied the full text of what I intended to reply with and put it on my website temporarily. It’s at: http://horton.sdf.org/tubes/pwrs-reply.txt

It’s got the netlists from what works and what doesn’t as well as the contents of my two init files. It’s just a text file. No nasty viruses or phishing.

Edit by bobc : add the intended text

I followed the instructions given by: http://ngspice.sourceforge.net/ngspice-eeschema.html#intro when I set it up. I’m using Windows 10, so I used the environment variable %USERPROFILE% to get where I was going. From there, I created first one file, then, when that did not work, the other.

Here’s what I’ve got:

C:\>cd %USERPROFILE%
C:\Users\Dave>type .spiceinit
* user provided init file
set ngbehavior=ps
C:\Users\Dave>type spice.rc
* user provided init file
set ngbehavior=ps
C:\Users\Dave>

I don’t think I’ve deviated from the instructions. I did restart KiCAD after creating each file. I still get Error: no such function 'pwrs'.

Here is my netlist for what does not work:

.title KiCad schematic
XU1 Out Net-R2-Pad1 Net-R3-Pad1 ECC83
R4 V+ Out 100k
R2 Net-R2-Pad1 Net-C1-Pad1 1k
R1 Net-C1-Pad1 GND 1Meg
R5 Out GND 1Meg
V2 In GND SIN(0 1 1k)
V1 V+ GND DC 250 AC 0
C1 Net-C1-Pad1 In 0.47u
R3 Net-R3-Pad1 GND 1.5k
.save @r4[i]
.save @r2[i]
.save @r1[i]
.save @r5[i]
.save @v2[i]
.save @v1[i]
.save @c1[i]
.save @r3[i]
.save V(In)
.save V(Net-C1-Pad1)
.save V(Net-R2-Pad1)
.save V(Net-R3-Pad1)
.save V(Out)
.save V(V+)
.SUBCKT ECC83 P G K
E1 2 0 VALUE={45+V(P,K)+95.43V(G,K)}
R1 2 0 1.0K
Gp P K VALUE={1.147E-6
(PWR(V(2),1.5)+PWRS(V(2),1.5))/2}
Cgk G K 1.6P
Cgp G P 1.7P
Cpk P K 0.46P
.ENDS ECC83
.tran 1m 2m
.end

Here is my netlist for what does work:

.title KiCad schematic
XU1 Out Net-R2-Pad1 Net-R3-Pad1 ECC83
R4 V+ Out 100k
R2 Net-R2-Pad1 Net-C1-Pad1 1k
R1 Net-C1-Pad1 GND 1Meg
R5 Out GND 1Meg
V2 In GND SIN(0 1 1k)
V1 V+ GND DC 250 AC 0
C1 Net-C1-Pad1 In 0.47u
R3 Net-R3-Pad1 GND 1.5k
.save @r4[i]
.save @r2[i]
.save @r1[i]
.save @r5[i]
.save @v2[i]
.save @v1[i]
.save @c1[i]
.save @r3[i]
.save V(In)
.save V(Net-C1-Pad1)
.save V(Net-R2-Pad1)
.save V(Net-R3-Pad1)
.save V(Out)
.save V(V+)
.SUBCKT ECC83 P G K
E1 2 0 VALUE={45+V(P,K)+95.43V(G,K)}
R1 2 0 1.0K
Gp P K VALUE={1.147E-6
(PWR(V(2),1.5)+SGN(V(2))*PWR(V(2),1.5))/2}
Cgk G K 1.6P
Cgp G P 1.7P
Cpk P K 0.46P
.ENDS ECC83
.tran 1m 2m
.end

The only change between the two netlists is me changing PWRS(V(2),1.5)) to SGN(V(2))*PWR(V(2),1.5))

Perhaps there is something else causing the problem? Is there any way to verify the init file is actually being read on startup? Is there a SPICE equivalent of a console.log()? Both init files have read-write permissions. I can’t think of what else it might be.

Probably confused by the @ signs. I suggest using triple backtick for anything code related.

Building reputation allows more features, mainly reading and liking posts help. There is a list somewhere.

I recall from a while ago that init files are not read in Windows, I think this still applies Is spinit or .spiceinit loaded (ngspice init files)

On Windows 10, I use a file with name spinit (no dot, and in the same folder where the schematic is) that contains:

ngbehavior=ltpsa

(which might be overkill).

Thanks @bobc. I appreciate you copying it over. I tried code blocks first, but it cut off part of my netlist after .SUBCKT, so I went with blockquote. But, you’re right, it’s the @v1, etc. that are being misinterpreted.

@franzee, I will try the spinit in the dir with the schematic. Thanks for the suggestion.

No, but you are no longer a new user so problem solved? :wink:

@hermit: If we’re going by age, I was never a “new user” to begin with. :slight_smile:

@franzee: I tried the spinit file you suggested in the directory with the schematic and still no luck. I get: Error: no such function 'pwrs'

D:\Users\Dave\Documents\Tube Amps\CommonCathode>dir
 Volume in drive D is DATA
 Volume Serial Number is 12DB-C3CB

 Directory of D:\Users\Dave\Documents\Tube Amps\CommonCathode

12/30/2020  06:09 PM    <DIR>          .
12/30/2020  06:09 PM    <DIR>          ..
12/30/2020  06:09 PM             2,690 CommonCathode-cache.lib
12/27/2020  10:50 PM                51 CommonCathode.kicad_pcb
10/30/2020  01:06 PM               688 CommonCathode.pro
12/30/2020  06:09 PM             4,596 CommonCathode.sch
12/30/2020  10:46 AM             4,605 CommonCathode.sch-bak
12/30/2020  06:06 PM                16 spinit
               6 File(s)         12,646 bytes
               2 Dir(s)  331,660,455,936 bytes free

D:\Users\Dave\Documents\Tube Amps\CommonCathode>type spinit
ngbehavior=ltpsa
D:\Users\Dave\Documents\Tube Amps\CommonCathode>

At this point, I’m not too concerned about it. I have a workaround with the prepending of SGN(V(2))*

Thanks everyone who helped me get to a working simulation. I appreciate your time and effort. If I have any epiphanies on getting the init file thing to work, I’ll post it here or an appropriate FAQ.

It is no poblem to run this netlist in recent ngspice, if properly set up.

Next step might be to check ngspice within KiCad (which differs from standard ngspice as it is using the simulator in a shared library). Could you please zip and upload all your KiCad files as found in
D:\Users\Dave\Documents\Tube Amps\CommonCathode?

I just came across another interesting feature (or bug) related to finding .spiceinit:

If another application has set a directory ‘HOME’ in Windows 10 to some arbitrary path, then ngspice shared library may fail to detect the .spiceinit (or spice.rc) file. This will be fixed in the next ngspice-34 release coming soon.

1 Like

Here is the ZIP file as requested. Please note, it is the version where I have replaced pwrs() with sgn() * pwr() as a workaround.

CommonCathode.zip (2.8 KB)

I am running KiCAD 5.1.8 on Windows 10 and I did some digging to see if I could determine the version of ngspice bundled with it, but no luck. Any KiCAD experts know where that information is kept or how to find it?

I also saw a new KiCAD 5.1.9 is out, so I will upgrade to the latest and see if that helps.

Thanks for your continued work on this.

As for the HOME environment. variables, the closest I could come to finding something like that was:

C:\Users\Dave>set | findstr HOME
HOMEDRIVE=C:
HOMEPATH=\Users\Dave
JAVA_HOME=C:\Program Files\Amazon Corretto\jdk1.8.0_265

I have GitSCM installed, which runs in a BASH shell in MINGW64 (a minimalist GNU install for Windows), but it is not my usual shell. I only mention it in the off chance that ngspice on Windows might also use MINGW64 and somehow they’re interfering.

Git BASH sets a $HOME, but it’s the Unix path equivalent of my Windows %USERPROFILE%.

$ env | grep HOME
JAVA_HOME=C:\Program Files\Amazon Corretto\jdk1.8.0_265
HOME=/c/Users/Dave
HOMEDRIVE=C:
HOMEPATH=\Users\Dave

I have just unzipped your files, and it is immediately clear what is happening:

If you add the subcircuit as a text box on the Eeschema window, it will simply be added to the netlist as text and sent to ngspice.

In this case, for obtaining PSPICE compatibility transformation, you will need the entry
set ngbehavior=psa
in .spiceinit. Only then the complete netlist will be transformed for PSPICE mode.

If you add the subcircuit from a file, e.g. ECC83.lib, into the ECC83 symbol by
‘double click’ on the symbol, ‘Edit Spice Model’
->Model->Select File->ECC83.lib->Type Subcircuit
then the model is loaded as a subcircuit by an
.include ECC.lib statement into the netlist. Only then
set ngbehavior=ps
is sufficient, because in this case ngspice transforms only subcircuits which are included into the netlist by the .include command.