ngspice/KiCad syntax error, bug, or undocumented features?

@holger Herr Holger, I am getting confused about some hidden syntax rules (or bugs?) in ngspice or in KiCad. The issue at hand this time is a weird interpretation of special characters that seems to be undocumented. For example, I created an XSPICE model for an inverter with hysteresis. Look at the lines showing various ways to define .model Analog_Hys hyst. I can use various characters like {xxx} or 'xxx' and the simulation works as expected. I can remove altogether all these symbols, except for the last lone one, and the simulation still works, but only if the last character is } and not '. If I remove the last lone character }, the simulation does not work anymore. And finally, if I keep only the last two characters ', the simulation works again. Is this the expected behavior, is there some documentation about it?

Mit freundlichen Grüßen,
Adi

*********************************************************************************************************
* RANGE is a SLEW RATE specific global parameter, not passed to the model
* BUFFER_SIZE provide discrete time step response precision (DELAY/BUFFER_SIZE)
* XSPICE Ngspice User Manual, Inverter and hysteresis
*
* PINSEQ:          1       = NULL FORBIDDEN, VECTOR NO, analog, input
*                  | 2     = NULL FORBIDDEN, VECTOR NO, analog, output
*                  | |
*******************|*|*******************************************************************************
.SUBCKT X0_INV_HYS 1 2 PARAMS:
+ VCC               = 3.3           // NULL PERMITTED, VECTOR NO, real, no limits (hidden vcc parameter default 3.3)
+ X_RT              = 2.0e-9        // NULL PERMITTED, VECTOR NO, real, no limits, technology internal raise time, (default 2.0e-9)
+ X_FT              = 2.0e-9        // NULL PERMITTED, VECTOR NO, real, no limits, technology internal fall time, (default 2.0e-9)
+ X_DU              = 2.0e-9        // NULL PERMITTED, VECTOR NO, real, no limits, technology delay unit, no default
+ X_CLK_DELAY       = {X_DU}        // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9), digital models only
+ X_SET_DELAY       = {X_DU}        // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9), digital models only
+ X_RESET_DELAY     = {X_DU}        // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9), digital models only
+ X_IC              = 0             // NULL PERMITTED, VECTOR NO, integer, 0 lower limit, 2 upper limit, output initial state (default 0)
+ X_DATA_LOAD       = 1.0e-12       // NULL PERMITTED, VECTOR NO, real, no limits, data loading capacitance (default 1.0e-12)
+ X_CLK_LOAD        = 1.0e-12       // NULL PERMITTED, VECTOR NO, real, no limits, clock loading capacitance (default 1.0e-12)
+ X_SET_LOAD        = 1.0e-12       // NULL PERMITTED, VECTOR NO, real, no limits, set loading capacitance (default 1.0e-12)
+ X_RESET_LOAD      = 1.0e-12       // NULL PERMITTED, VECTOR NO, real, no limits, reset loading capacitance (default 1.0e-12)
+ X_INPUT_LOAD      = 1.0e-12       // NULL PERMITTED, VECTOR NO, real, no limits, input loading capacitance (default 1.0e-12)
+ X_RISE_DELAY      = {X_DU}        // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9)
+ X_FALL_DELAY      = {X_DU}        // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9)
+ X_T_RISE          = {X_DU}        // NULL PERMITTED, VECTOR NO, real, no limits, hybrid XHDA_Bridge models only
+ X_T_FALL          = {X_DU}        // NULL PERMITTED, VECTOR NO, real, no limits, hybrid XHDA_Bridge models only
+ X_HAS_DELAY_CNT   = 0             // NULL PERMITTED, VECTOR NO, boolean, FALSE uses {delay}, TRUE uses cntrl input (default 0)
+ X_DELMIN          = {X_RT+X_FT}   // NULL PERMITTED, VECTOR NO, real, 0 lower limit, no upper limit (default 0)
+ X_DELMAX          = {20*X_DELMIN} // NULL PERMITTED, VECTOR NO, real, 0 lower limit, no upper limit (default 0)
+ X_DELAY           = {X_DELMIN/3}  // NULL PERMITTED, VECTOR NO, real, no limits (default 0)
+ X_BUFFER_SIZE     = 1024          // NULL PERMITTED, VECTOR NO, integer, 1 lower limit, no upper limit (default 1024)
+ X_RAISE_SLOPE     = {1/X_Rt}      // NULL PERMITTED, VECTOR NO, real, no limits, (Default = 1.0e9), set in V/s, 0.5G for Vcc = 1
+ X_FALL_SLOPE      = {1/X_Ft}      // NULL PERMITTED, VECTOR NO, real, no limits, (Default = 1.0e9), set in V/s, 0.5G for Vcc = 1
+ X_RANGE           = 0.1           // NULL PERMITTED, VECTOR NO, real, no limits, (Default = 0.1), for SLEW RATE only
+ X_IN_LOW          = {VCC*0.66}    // NULL PERMITTED, VECTOR NO, real, no limits (default 1.0), analog and hybrid models only
+ X_IN_HIGH         = {VCC*0.33}    // NULL PERMITTED, VECTOR NO, real, no limits (default 2.0), analog and hybrid models only
+ X_HYST            = {VCC*0.1}     // NULL PERMITTED, VECTOR NO, real, 0 lower limit, no upper limit (Default = 0.1)
+ X_OUT_LOWER_LIMIT = 0             // NULL PERMITTED, VECTOR NO, real, no limits (Default = 0)
+ X_OUT_UPPER_LIMIT = {VCC}         // NULL PERMITTED, VECTOR NO, real, no limits (Default = 1)
+ X_INPUT_DOMAIN    = 0.01          // NULL PERMITTED, VECTOR NO, real, no limits (Default = 0.1), input smoothing domain
+ X_FRACTION        = 1             // NULL PERMITTED, VECTOR NO, boolean 0 or 1 (default 1)
+ X_OUT_LOW         = 0             // NULL PERMITTED, VECTOR NO, real, no limits, hybrid and analog models only
+ X_OUT_HIGH        = {VCC}         // NULL PERMITTED, VECTOR NO, real, no limits, hybrid and analog models only
+ X_OUT_UNDEF       = {VCC/2}       // NULL PERMITTED, VECTOR NO, real, no limits, defaults to the arithmetic mean, hybrid XHDA_Bridge models only

* MODELS SECTION
*.model Analog_Hys hyst (in_low='X_IN_LOW' in_high='X_IN_HIGH' hyst='X_HYST' out_lower_limit='X_OUT_LOWER_LIMIT' out_upper_limit='X_OUT_UPPER_LIMIT' input_domain='X_INPUT_DOMAIN' fraction='X_FRACTION')
*.model Analog_Hys hyst (in_low={X_IN_LOW} in_high={X_IN_HIGH} hyst={X_HYST} out_lower_limit={X_OUT_LOWER_LIMIT} out_upper_limit={X_OUT_UPPER_LIMIT} input_domain={X_INPUT_DOMAIN} fraction={X_FRACTION})
*.model Analog_Hys hyst (in_low=X_IN_LOW in_high=X_IN_HIGH hyst=X_HYST out_lower_limit=X_OUT_LOWER_LIMIT out_upper_limit=X_OUT_UPPER_LIMIT input_domain=X_INPUT_DOMAIN fraction=X_FRACTION})
.model Analog_Hys hyst (in_low=X_IN_LOW in_high=X_IN_HIGH hyst=X_HYST out_lower_limit=X_OUT_LOWER_LIMIT out_upper_limit=X_OUT_UPPER_LIMIT input_domain=X_INPUT_DOMAIN fraction='X_FRACTION')
*
.model my_inverter d_inverter (rise_delay='X_RISE_DELAY' fall_delay='X_FALL_DELAY' input_load='X_INPUT_LOAD')
*
* HYSTERESIS SECTION
A_HYST 1 12 Analog_Hys
*
* INVERTER SECTION
A_INV 12 2 my_inverter
*
.ENDS X0_INV_HYS

*$

The rule is to put parameters to be replaced into {…}.

Anything else may work (for compatibility reasons with externally provided models), but there may be corner cases which do not work.

In addition, traditionally ngspice did not allow ‘-’ in a subcircuit name. You need to set the compatibility mode to PS and LT to enable it.

We have to check if we generally may allow ‘-’.

Could you please elaborate a bit on this subcircuit name restriction? I have really hard time to understand why the name with “-” is sometimes rejected (randomly, bug?). It is quite tedious to change countless file names, symbol fields, and internal references.

The ngspice manual states in many places There is no restriction on the file name imposed by ngspice beyond those imposed by the local operating system.

1 Like

We do not talk about file names, but subcircuit names. These may contain numbers, letters, _, [, ] If the compatibilty mode is set to ltpsa, - is allowed as well.

Why? Because it is programmed like this.

To set ltpsa, open Simulator Window, → Edit Analysis Tab, set ‘Compatibility mode’ to ‘PSPICE and LTSPICE’.

I will add ‘-’ permanently to the characters allowed (available in ngspice-45).

2 Likes