Electronic – Alternatives to LTSpice that are more digitally oriented?

simulationspice

What other alternatives do we have for circuit simulation?

In particular I would be very interested to find a tool that would allow me to simulate digital components by running C code snippets that are able to generate the output signals and then these signals would be fed into passive component simulator that will do the simulation and feed resulting signals into other digital parts that are simulated in C.

I don't want to have to design mock ups for every digital component out of voltage sources and passive components. I want to just write code to generate the output signals.

Best Answer

I found what I wanted after reading documentation for the xspice module available in ngspice. It allows me to write models for my digital components in C and then simulate peripheral discrete components using existing spice models for transistors, resistors etc. I'm still experimenting with this feature but so far it has been very promising because I can model any firmware based digital controller in between inputs and outputs of a digital component defined in the schematic.

Here is a small throwaway example of a custom pwm component: enter image description here

I then export this as a spice netlist from kicad:

* Sheet Name: /
A1  Net-_A1-Pad1_ GND Net-_A1-Pad3_ Net-_A1-Pad4_ MKPWM01
V1  Net-_A1-Pad1_ GND 3.3v
R3  OUT GND 50k
R2  Net-_A1-Pad3_ GND 10k
R1  Net-_A1-Pad1_ Net-_A1-Pad3_ 10k
C1  OUT GND 10n
R4  OUT Net-_A1-Pad4_ 50k

.end

Then I add a little wrapper script where I add ngspice commands for my circuit:

.model mkpwm01 mkpwm01 (freq = 100)

.include "spice_test.cir"

.control
tran 1ms 100ms
plot v(OUT)
.endc

.end

And finally I add code model for mkpwm component under src/xspice/icm and then compile ngspice:

void cm_d_mkpwm01(ARGS) {               
    if (ANALYSIS == DC || ANALYSIS == TRANSIENT) {
        double out = sin(TIME * PARAM(freq) * 2.f * M_PI);

        if(out > 0) out = INPUT(vcc);   
        else out = INPUT(gnd);          

        OUTPUT(out) = out;              
    }   
}       

And the model definition (.ifs) file:

NAME_TABLE:

Spice_Model_Name:      mkpwm01          
C_Function_Name:       cm_d_mkpwm01     
Description:           "pwm generator"  


PORT_TABLE:

Port_Name:           vcc                gnd             in                 out
Description:         "vcc"              "gnd"           "input"            "output"
Direction:           in                 in              in                 out
Default_Type:        v                  v               v                  v
Allowed_Types:       [v]                [v]             [v]                [v]
Vector:              no                 no              no                 no
Vector_Bounds:       -                  -               -                  -
Null_Allowed:        no                 no              no                 no


PARAMETER_TABLE:

Parameter_Name:     freq                
Description:        "frequency"         
Data_Type:          real
Default_Value:      1                   
Limits:             [1e-12 -]           
Vector:              no                 
Vector_Bounds:       -                  
Null_Allowed:       yes           

Then finally running the wrapper script produces the result:

enter image description here

Very happy so far. Now time to simulate a more complex circuit :-)

Note: I originally added the xspice component as a digital component but that did not work because I got error "node can not be both digital and analog" so I had to change the pins to be analog (type v). The ngspice manual explains different pin types. Also the duty cycle input is not really implemented in the code.. Anyway, I still probably have a lot to learn how xspice api works but so far I think I found exactly what I need and hopefully this helps someone to start using ngspice for customized circuit simulation.