[Sim.Library] keyword: KiCad, ngspice, or Linux/Windows doomsday bug?

There is a bug (KiCAD 9.0 under Linux) regarding the keyword [Sim.Library]: it will not recognize the [DEFAULT_ngspice] location if that location is declared the normal way as a regular folder, probably because I declared the field as a Template URL for quick access to the model. For this [Sim.Library] keyword, instead of using the regular location, you have to use a link pointing to a network file server location [file:///home/work/projects/000_KiCAD/_lib/ngspice/BIP-NPN.sp]. That’s why, instead of using the [Sim.Library] for quick access to the spice model, we need to duplicate this field with another one named [Model File] for example, and declare this one an URL pointing to [${DEFAULT_ngspice}/BIP-NPN.sp]. Probably in Windows we do not have this bug, maybe the issue is with Linux only. In short, the field [Sim.Library] will not accept the value [${DEFAULT_ngspice}/BIP-NPN.sp] (that is, a regular folder location) and instead we need to use the value [file:///home/work/projects/000_KiCAD/_lib/ngspice/BIP-NPN.sp] (that is, a network file server location). I have seen on Internet some issues pointing to the MIME type, maybe there is where the bug is coming from.

Also, maybe related or not, the field [Model File] with the value [${DEFAULT_ngspice}/BIP-NPN.sp] does not show the visual ICON hint of a hyperlink (see below) when the property is checked in the library editor (I declared it Template type URL). The [Sim.Library] field shows, as expected, the Template URL association through that small ICON. Even so, when the symbol is placed in the schematic the [Model File] field is an URL template, and it can be used to access the model.

Operating System: CachyOS Linux
KDE Plasma Version: 6.3.4
KDE Frameworks Version: 6.12.0
Qt Version: 6.8.3
Kernel Version: 6.14.0-4-cachyos (64-bit)
Graphics Platform: Wayland
Processors: 20 × Intel® Core™ i9-9900X CPU @ 3.50GHz
Memory: 125.5 GiB of RAM
Graphics Processor: NVIDIA TITAN RTX

Application: KiCad Symbol Editor x86_64 on x86_64
Version: 9.0.1, release build
Libraries:
wxWidgets 3.2.7
FreeType 2.13.3
HarfBuzz 11.0.0
FontConfig 2.16.1
libcurl/8.13.0 OpenSSL/3.4.1 zlib/1.3.1.zlib-ng brotli/1.1.0 zstd/1.5.7 libidn2/2.3.7 libpsl/0.21.5 libssh2/1.11.1 nghttp2/1.65.0 nghttp3/1.8.0
Platform: CachyOS, 64 bit, Little endian, wxGTK, Wayland, KDE, wayland
OpenGL: NVIDIA Corporation, NVIDIA TITAN RTX/PCIe/SSE2, 4.6.0 NVIDIA 570.133.07
Build Info:
Date: Mar 31 2025 07:50:52
wxWidgets: 3.2.7 (wchar_t,wx containers) GTK+ 3.24
Boost: 1.87.0
OCC: 7.8.1
Curl: 8.12.1
ngspice: 44.2
Compiler: GCC 14.2.1 with C++ ABI 1019
Build settings:
KICAD_USE_EGL=ON
KICAD_IPC_API=ON
Locale:
Lang: en_US
Enc: UTF-8
Num: 1,234.5
Encoded кΩ丈: D0BACEA9E4B888 (sys), D0BACEA9E4B888 (utf8)

Edit:
To make matters even worse, the previous [file:///home/work/projects/000_KiCAD/_lib/ngspice/BIP-NPN.sp] is working randomly, now it is not finding the model anymore:

I have to use now the absolute path to get access and find my ngspice model:

This issue is very bad. It will not allow me to create and maintain a library since I will have to modify thousands of symbols on a daily basis, on multiple copies of that library, in multiple locations. I cannot make a portable library to be accessed in multiple locations.

Also, the Simulation Model Editor is not an editor at all, it is a Simulation Model Viewer. I cannot edit the model there, unless is something else wrong with KiCad in Linux.

I had to check in Windows, and seems we have much bigger problems there. Windows simply cannot differentiate between underline character “_” and minus sign “-”, as shown below. KiCad kept sending error messages, and I was able to chase down the issue to messed-up Windows characters. Is this a doomsday bug? If Windows is messing up characters, how much we can count on the right file location, and the content in the files? Is this a common problem, somebody else encountered this bug?
KiCad error message:
List of plots available:
Current const Constant values (constants)
Note: Codel model file loading path is C:\Users\u212808\work\01_projects_KiCAD\0011_Demo_Supply\002_kiSPICE\001-1_Logic_Driver
Note: No compatibility mode selected!
Error: Mismatch of .subckt … .ends statements!
in file circbyline
This will cause subsequent errors.
Check line .subckt xdd_d-flop 1 2 3 4 5 6 (in the file xdd_d_flop.sp)
Error: ngspice.dll cannot recover and awaits to be reset or detached
Windows error: NOTE the keyword I searched for “xdd_d_flop.sp” and the returned result “xdd_d-flop.sp

Please provide a small project demonstrating this bug.

For me it is not possible to follow the chain of errors just by staring at some image.

Herr Holger, I attached here an example. Unfortunately you have to re-create the scenario where you place the files in various location with “_” and “-” in the name, KiCad is not “self-contained” in that way. Please let me know if there are any sym or lib files I missed to add. For reference, I am showing here some of the path settings I have in Windows. Note, I tried to define some of the fields as URL Template; even these link settings are not working as expected, I can elaborate on this extra issue.

001-1_Logic_Driver.7z (58.2 KB)

One more bit of information for KiCad under Windows (maybe also Linux). If I replace the name “XDD_D-FLOP.sp” with “XDD_D_FLOP.sp” all over in the symbol, the file name, and the model content (replace minus character with underline character), then I can get the simulation working. This to me looks like a collection of multiple different bugs, affecting KiCad, Linux, and Windows, unless the minus character is forbidden now.

*
* Daddyzaur's models
* http://www.daddyzaur.com/
*
*********************************************************************************************************
* XSPICE Ngspice User Manual, D Flip Flop
*
* PINSEQ:          1           = NULL FORBIDDEN, VECTOR NO, digital, input data
*                  | 2         = NULL FORBIDDEN, VECTOR NO, digital, input clk
*                  | | 3       = NULL FORBIDDEN, VECTOR NO, digital, input asynch. set
*                  | | | 4     = NULL FORBIDDEN, VECTOR NO, digital, input asynch. reset
*                  | | | | 5   = NULL FORBIDDEN, VECTOR NO, digital, output data
*                  | | | | | 6 = NULL FORBIDDEN, VECTOR NO, digital, output inverted data
*                  | | | | | |
*******************|*|*|*|*|*|***************************************************************************
.SUBCKT XDD_D_FLOP 1 2 3 4 5 6
*
.PARAMS // GLOBAL Digital XSPICE default values (overwritten per Digital component if internally re-defined)
+ VCC             = {X_VCC}                    // NULL PERMITTED, VECTOR NO, real, no limits (default 1.0)
+ RT              = {X_RT}                     // NULL PERMITTED, VECTOR NO, real, no limits, technology internal raise time, (default 2.0e-9)
+ FT              = {X_FT}                     // NULL PERMITTED, VECTOR NO, real, no limits, technology internal fall time, (default 2.0e-9)
+ DU              = {X_DU}                     // NULL PERMITTED, VECTOR NO, real, no limits, technology delay unit, no default
+ CLK_DELAY       = {X_CLK_DELAY}              // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9)
+ SET_DELAY       = {X_SET_DELAY}              // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9)
+ RESET_DELAY     = {X_RESET_DELAY}            // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9)
+ IC              = {X_IC}                     // NULL PERMITTED, VECTOR NO, integer, 0 lower limit, 2 upper limit, output initial state (default 0)
+ DATA_LOAD       = {X_DATA_LOAD}              // NULL PERMITTED, VECTOR NO, real, no limits, data loading capacitance (default 1.0e-12)
+ CLK_LOAD        = {X_CLK_LOAD}               // NULL PERMITTED, VECTOR NO, real, no limits, clock loading capacitance (default 1.0e-12)
+ SET_LOAD        = {X_SET_LOAD}               // NULL PERMITTED, VECTOR NO, real, no limits, set loading capacitance (default 1.0e-12)
+ RESET_LOAD      = {X_RESET_LOAD}             // NULL PERMITTED, VECTOR NO, real, no limits, reset loading capacitance (default 1.0e-12)
+ INPUT_LOAD      = {X_INPUT_LOAD}             // NULL PERMITTED, VECTOR NO, real, no limits, input loading capacitance (default 1.0e-12)
+ RISE_DELAY      = {X_RISE_DELAY}             // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9)
+ FALL_DELAY      = {X_FALL_DELAY}             // NULL PERMITTED, VECTOR NO, real, 1.0e-12 lower limit, no upper limit (default 1.0e-9)
+ T_RISE          = {X_T_RISE}                 // NULL PERMITTED, VECTOR NO, real, no limits, hybrid XHDA_Bridge models only
+ T_FALL          = {X_T_FALL}                 // NULL PERMITTED, VECTOR NO, real, no limits, hybrid XHDA_Bridge models only
+ HAS_DELAY_CNT   = {X_HAS_DELAY_CNT}          // NULL PERMITTED, VECTOR NO, boolean, FALSE uses {delay}, TRUE uses cntrl input (default 0)
+ DELMIN          = {X_DELMIN}                 // NULL PERMITTED, VECTOR NO, real, 0 lower limit, no upper limit (default 0)
+ DELMAX          = {X_DELMAX}                 // NULL PERMITTED, VECTOR NO, real, 0 lower limit, no upper limit (default 0)
+ DELAY           = {X_DELAY}                  // NULL PERMITTED, VECTOR NO, real, no limits (default 0)
+ BUFFER_SIZE     = {X_BUFFER_SIZE}            // NULL PERMITTED, VECTOR NO, integer, 1 lower limit, no upper limit (default 1024)
+ RAISE_SLOPE     = {X_RAISE_SLOPE}            // NULL PERMITTED, VECTOR NO, real, no limits, (Default = 1.0e9), set in V/s
+ FALL_SLOPE      = {X_FALL_SLOPE}             // NULL PERMITTED, VECTOR NO, real, no limits, (Default = 1.0e9), set in V/s
+ RANGE           = {X_RANGE}                  // NULL PERMITTED, VECTOR NO, real, no limits, (Default = 0.1), for SLEW RATE only
+ IN_LOW          = {X_IN_LOW}                 // NULL PERMITTED, VECTOR NO, real, no limits (default 1.0)
+ IN_HIGH         = {X_IN_HIGH}                // NULL PERMITTED, VECTOR NO, real, no limits (default 2.0)
+ HYST            = {X_HYST}                   // NULL PERMITTED, VECTOR NO, real, 0 lower limit, no upper limit (Default = 0.1)
+ OUT_LOWER_LIMIT = {X_OUT_LOWER_LIMIT}        // NULL PERMITTED, VECTOR NO, real, no limits (Default = 0)
+ OUT_UPPER_LIMIT = {X_OUT_UPPER_LIMIT}        // NULL PERMITTED, VECTOR NO, real, no limits (Default = 1)
+ INPUT_DOMAIN    = {X_INPUT_DOMAIN}           // NULL PERMITTED, VECTOR NO, real, no limits (Default = 0.1), input smoothing domain
+ FRACTION        = {X_FRACTION}               // NULL PERMITTED, VECTOR NO, boolean 0 or 1 (default 1)
+ OUT_LOW         = {X_OUT_LOW}                // NULL PERMITTED, VECTOR NO, real, no limits
+ OUT_HIGH        = {X_OUT_HIGH}               // NULL PERMITTED, VECTOR NO, real, no limits
+ OUT_UNDEF       = {(X_OUT_LOW+X_OUT_HIGH)/2} // NULL PERMITTED, VECTOR NO, real, no limits, defaults to the arithmetic mean
*
A_D_FLOP 1 2 3 4 5 6 Digital_D_FLOP
.model Digital_D_FLOP d_dff (reset_delay={RESET_DELAY} set_delay={SET_DELAY} clk_delay={CLK_DELAY} ic = {IC}
+ data_load={DATA_LOAD} clk_load={CLK_LOAD} set_load={SET_LOAD} reset_load={RESET_LOAD}
+ rise_delay={RISE_DELAY} fall_delay={FALL_DELAY})
*
.ENDS XDD_D_FLOP

*$