Commit Graph
7920 Commits
Author SHA1 Message Date
Holger Vogt 8ecfc073a8 Improved error handling in case of faulty .lib line 2026-08-07 16:39:16 +02:00
Holger Vogt 0bd394dc7a examples/xspice/filesource/filesource_variants.cir fails with compatmode ps.
Replace strstr by search_plain_identifier to not falsely read t_abs out
of rect_abs_dual.m
2026-08-03 17:06:35 +02:00
Meisam BahadoriandClaude Opus 4.8 75009e9afc * Enhancement-306: ngspice — the E-241 twin in the fft expression function
Enhancement-241 fixed an amplitude normalization that divided by the ZERO-PADDED
transform size instead of the number of input samples -- in the `fft` COMMAND
(frontend/com_fft.c). The identical mistake survived in maths/cmaths/cmath4.c, the
vector-expression function reached by `let F = fft(v)`: a separate implementation of
the same computation.

Found by continuing the oracle campaign that produced E-241, and located with E-241's
own discriminator, the DC bin. One signal, 4001 samples padded to 4096, DC offset 2.0:

  fft s          ; the COMMAND    ->  mag(s)[0] = 2.000000    correct
  let F = fft(s) ; the FUNCTION   ->  mag(F)[0] = 1.953613    = 2.0 * 4001/4096

X[0] is the sum of the samples, D*length for a DC offset D, so dividing by the padded N
reads back D*length/N. As E-241 put it: a DC value cannot depend on how many samples
were taken.

This is a contradiction, not a matter of convention. cx_fft holds TWO complete
implementations -- one for complex input, one for real -- and each has an FFTW branch
and a Green's radix-2 branch. In BOTH, the FFTW branch already used the input length
while Green's used the padded size:

  real branch     FFTW: scale = ((double)length)/2.0    Green: ((double)N)/2   <- wrong
  complex branch  FFTW: scale = (double) fpts           Green: (double) N      <- wrong

the correct version sitting a few lines from the wrong one inside the same function --
the same shape as `avg` disagreeing with `integ` in E-302. HAVE_LIBFFTW3 is undefined in
this build, so Green's is the live path and the defect was reachable.

  oracle                              before      after       closed form
  real-input, DC bin                  1.953613    2.000000    2.0
  real-input, ifft(fft(x))            2.3e-02     1.1e-16     0
  complex-input, bin 0                0.9766780   0.9998683   0.9998683

The round trip is an INDEPENDENT confirmation: nothing here touches ifft, so its going
from 2.3% error to machine precision is evidence from a direction the fix did not aim
at -- the pair only inverts when the forward normalization is right. cx_ifft was
audited and deliberately left alone for that reason.

Every caller of the Green's radix-2 kernel was audited, not only the one that failed:
com_fft.c's fft (x2) and spec/PSD (x2) are correct from E-241; cx_ifft is correct;
trannoise/1-f-code.c cannot pad at all, since n_pts is grown to 2^n_exp by construction;
and fft/ifft are the only transform functions in the expression table, so there is no
spec twin to miss.

Verification: examples/fftexpr_examples/verify_fftexpr.py -- 6 checks under both
solvers, all against closed form (DC bin on both paths, round trip padded and unpadded,
complex-input bin 0 against the analytic mean of an RC response). It scores 3/6 on the
pre-fix binary, so it is a real regression guard. E-241's own suite (fftnorm_examples)
and ifftreal_examples pass unchanged. Full sweep 241/241 OK.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-03 17:06:00 +02:00
Meisam BahadoriandClaude Opus 4.8 28b3cb831b * E-252: XSPICE xfer/file_source — fix two heap out-of-bounds writes in the file parsers
Found while sweeping the file-parser code models (d_state/d_source/xfer/
file_source); confirmed with AddressSanitizer. Unlike the earlier code-model
finds (E-246/247/250, reads or bounded errors), these are out-of-bounds WRITES --
silent heap corruption.

1. xfer (analog/xfer/cfunc.mod, read_file): reads a transfer-function file (a
   Touchstone-style `#` option line then data). It sscanf's up to 9 values per
   line and a state machine stores every value (freq/real/imag triples), so a
   line with more than one record stores more than 3. The allocation check
   reserved only 3 (`if (i + 3 > size)`, ALLOC=1024), so a multi-record line
   wrote past the buffer at the 1024-double boundary (ASan: heap-buffer-overflow
   WRITE, cm_xfer). Fix: reserve the sscanf maximum of 9 (`if (i + 9 > size)`).

2. file_source (analog/file_source/cfunc.mod): stores one record per line -- a
   timepoint plus `size` channel values = stepsize (size+1) doubles -- but
   reserved only `size` (`vecallocated - size`), one short. At the reallocation
   boundary the final channel wrote one double past the end (ASan:
   heap-buffer-overflow WRITE, cm_filesource). Fix: reserve a full record
   (`- stepsize`).

Both are heap OOB writes reachable from a valid-syntax netlist with a crafted
data file; the release build corrupts adjacent heap silently rather than always
crashing (UB either way). The sibling parsers were checked: d_source validates
its per-line token count against the declared width, and d_state's fixed line
buffer is fgets-bounded -- no analogous overrun.

Code-model-only change: analog.cm regenerated via cmpp and redeployed under
bin/*/codemodels/; the ngspice binary is unchanged. Verify
(examples/filefix_examples, 4 checks x2 solvers): valid transfer-function and
file_source files simulate; an xfer multi-record file and a boundary-crossing
file_source file run without overrunning. Both reproduced under ASan and shown
fixed. Full regression 208/208.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-03 17:05:51 +02:00
Meisam BahadoriandClaude Opus 4.8 7920f3fa38 * E-241: fft/spec — fix amplitude normalization for non-power-of-2 records
First numerical-correctness (wrong-number, not crash) find of a correctness-audit
campaign that checked ngspice analyses against analytic and numpy oracles.
com_fft.c has two paths: FFTW3 (exact length-point transform, scale=length/2,
correct) and a Green's radix-2 FFT (no FFTW3) that zero-pads the `length` input
samples up to the next power of two N. The non-FFTW path normalized the
single-sided amplitude by the PADDED size (scale=N/2) instead of the true sample
count (length/2), so every FFT whose sample count is not a power of two reported
amplitudes too small by length/N -- up to 2x. A .tran essentially never yields
exactly 2^k points, so this bit the common case silently. The DC bin is the clean
discriminator (always exactly bin 0, no scalloping): a 2.0 V DC offset read back
as 2.0*length/N, e.g. 1.0009 for a 1025-sample record padded to 2048. spec had
the same error in its power normalization (intres = N*N instead of length*length;
the FFTW path already used length*length).

Fix: scale = length/2 and intres = length*length in the non-FFTW path, matching
FFTW. The frequency axis was already padding-aware, so only the magnitude scale
needed changing; power-of-2 records (length == N) and FFTW-linked builds are
unchanged. Validated against numpy: after the fix ngspice's fft matches
numpy.fft.rfft of the same zero-padded record (normalized by length) bin-by-bin
to ~1e-9. fft/spec amplitudes now change for non-power-of-2 records (they become
correct). Regression 199/199.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-03 17:05:38 +02:00
Holger Vogt 40078850f4 Enable spice notations like 2n or 5m in filesource inputs
Tests that spaces or tabs are o.k.
2026-08-03 17:05:28 +02:00
Holger Vogt 2dbbb68e63 switch to Unix line endings 2026-08-03 17:05:15 +02:00
Holger Vogt a3662ba76e Revert "ckt: dangling-passive topology reduction"
This reverts commit 9575899a95.
2026-07-31 14:12:22 +02:00
Holger Vogt f5754446c0 Revert "no removal of dangling capacitors/resistors when rshunt is set"
This reverts commit b020c83b86.
2026-07-31 14:12:08 +02:00
Holger Vogt ee38134f63 Revert "enable removal of dangling nodes also when MODETRANOP is set."
This reverts commit 4fb403a590.
2026-07-31 14:11:47 +02:00
Holger Vogt 47c77e421d Revert "If stricterrorhandling is set, ngspice detects the dangling"
This reverts commit 02c6478399.
2026-07-31 14:11:26 +02:00
Holger Vogt fa8b6756bb Revert "Enable obtaining node info also for code models."
This reverts commit 08f4b56de5.
2026-07-31 14:11:02 +02:00
Holger Vogt f82cc35ce2 Revert "Disable topology reduction by default. Enable it by setting"
This reverts commit 39c662c12b.
2026-07-31 14:10:46 +02:00
Meisam Bahadori a14c6822a0 Add missing files to pyplot 2026-07-19 17:37:43 +02:00
Holger Vogt 6d2335d1f7 Avoid freeing a non-malloced entry 2026-07-19 17:37:14 +02:00
Meisam Bahadori 7caaa1f68b Add command 'pyplot', invoking numpy/matplotlib plotting,
similar to 'gnuplot' (Meisam Bahadori and Claude 4.8).
Commit contains Enhancements 94, 95, 98, 99, 182, 183.
Add a plotting flag 'boxesplot', in addition to 'combplot'
This fixes a bug in gnuplot and pyplot,
now offering both distinct combplot and boxesplot. (H. Vogt).
2026-07-19 17:37:04 +02:00
MeisamandClaude Fable 5 133f118c66 Adds a 'pyplot' interactive command that renders simulated vectors with
matplotlib -- a Python counterpart to ngspice's 'gnuplot' command. Same
syntax (pyplot <file> <plot expressions...>): the first word is the output file name only when it is NOT a plot expression, the rest are ordinary plot expressions handled by plotit().

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-19 17:36:40 +02:00
Holger Vogt 39c662c12b Disable topology reduction by default. Enable it by setting
'topo_reduce' in .spiceinit.
2026-07-19 17:36:31 +02:00
Holger Vogt 08f4b56de5 Enable obtaining node info also for code models. 2026-07-19 17:36:09 +02:00
Holger Vogt 02c6478399 If stricterrorhandling is set, ngspice detects the dangling
capacitors and resioiostors, lists them and then bails out.
2026-07-19 17:35:37 +02:00
Holger Vogt 4fb403a590 enable removal of dangling nodes also when MODETRANOP is set.
Removes singular nodes when op before tran is run.
2026-07-19 17:35:23 +02:00
Holger Vogt b020c83b86 no removal of dangling capacitors/resistors when rshunt is set 2026-07-19 17:35:02 +02:00
alto555andClaude Opus 4.8 9575899a95 ckt: dangling-passive topology reduction
Add CKTtopologyReduce() (cktsetup.c) to remove degree-1 dangling
capacitors/resistors -- e.g. dead-end opamp compensation caps -- that
otherwise cause spurious 'Timestep too small' aborts. Node degree is
counted generically over all device types; the floating node is pinned
with a unit diagonal. Disable with 'set no_topo_reduce'.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-19 17:34:52 +02:00
Holger Vogt b8ae73d4a2 typo 2026-07-19 17:30:54 +02:00
Holger Vogt 3f7f438f0a Warn if rshunt without XSPICE selected 2026-07-19 17:30:47 +02:00
Holger Vogt 7fc36269b8 Improve the output format of the 'show' command,
tested with various voltage sources.
2026-07-19 17:30:35 +02:00
Holger Vogt 58600e5db1 Restrict the return vectors (malloced) to the voltage source type
given by the requested VSRC function type value (VSRC_PULSE etc.)
2026-07-19 17:30:29 +02:00
Peer Hofstra 9d385d512c Strip a UTF-8 byte order mark at the start of a line -- i.e. at
the start of a file written by a Windows editor.  A BOM is never
legal SPICE syntax; left in place it glues to the first token
(fatal ".subckt/.ends mismatch" class errors in included libs).
2026-07-19 17:30:10 +02:00
alto555andClaude Opus 4.8 b2ec82609e `show' printed a device's vector parameter (a source's pulse/pwl/ac
coefficient list) one element at a time, calling askInstanceQuest for
every element.  Two bugs made that catastrophic on a large chip:

  * IFvalue val was uninitialised, so a query that did not set
    v.numValue left `n' as stack garbage -- the element loop then ran
    essentially forever.
  * askInstanceQuest TMALLOCs the coefficient vector (vsrcask.c) on
    every call and printvals()/printvals_old() never freed it, so the
    listing leaked O(n^2) allocations -- tens of GB on a deck with many
    stimulus sources.

Fix: memset val before the query and clamp n (kills the runaway loop),
and free the returned vector after use via a new free_if_vec() helper.
Verified: pulse coefficients still print correctly; show on MOS/BSIM4/
OSDI/vsource is unchanged and does not crash.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-17 11:44:41 +02:00
Giles Atkinson 692c5a3f95 Fix file name quoting for .LIB. Reported by Tom Hajar in ngspice-users. 2026-07-08 22:47:41 +02:00
Giles Atkinson 1123808aec Correct three comments. 2026-07-08 22:46:54 +02:00
Giles Atkinson 2c2bc4f435 In a shared library build, the option -fvisibility=hidden may be set
when compiling making entry point Cosim_setup inaccessible.  The problem
was reported at https://github.com/iic-jku/IIC-OSIC-TOOLS/issues/287,
but not reproduced.
2026-07-08 22:46:42 +02:00
Holger Vogt 9230554e26 Make the name of the added voltage source more verbose
(to avoid already existing source names).
2026-07-08 22:46:31 +02:00
Giles Atkinson 08d97e6f09 Fix Bug #775 - "Missing LDFLAGS in vlnggen", and add an option
(-stc c++14) that was needed in testing on Windows.
2026-07-08 22:46:16 +02:00
Giles Atkinson cb5fbed1f9 Feature Request 72 - "Printing hidden errors to terminal" suggests
showing errors in XSPICE code model support functions by default.
But errors may occur routinely and be handled by code.
To aid developers, setting variable "noisyxspice" will display the messages.

Also fix an error report in cm_event_queue(), remove XSPICE parse error
messages that are now shown twice and fix errors in d_source that
were seen with the new error reporting.
2026-07-08 22:45:58 +02:00
Giles Atkinson 0f0f80f34f Add new capabilities to the adc/dac_bridge XSPICE code models.
If either bridge has a single analog connection and two or more digital
connections it will act as a conventional multi-bit ADC or DAC.
When the low threshold is higher than the high threshold, adc_bridge
acts as a Schmitt trigger.
2026-07-08 22:45:21 +02:00
Giles Atkinson 37b6fda497 Simplify adc_bridge, also removing excess white space. 2026-07-08 22:44:59 +02:00
Holger Vogt 62f0b2d8cc New behavioral capacitor model:
- Replace E source by G source with parallel resistor to improve
  convergence.
- Add parallel resistor to avoid floating nodes
- Reduce refecrence C to 1u (and thus the max. current).
2026-07-08 22:44:49 +02:00
Holger Vogt c961118650 Add error message if scale and data vector lengths do not match 2026-07-08 22:44:28 +02:00
Holger Vogt 8c68d55067 Update the copyright notice 2026-07-08 22:44:21 +02:00
Holger Vogt d7db4192a8 Replace lengthy call to CKTcircuit by new TSTOP and TSTEP macros 2026-07-08 22:44:10 +02:00
Holger Vogt 28df521b11 Set TSTEP and TSTOP also when MIF_DC, as this is needed
when initialising a code model during op before a tran sim.
2026-07-08 22:43:56 +02:00
Holger Vogt e2f397f9b5 Add two macros TSTEP and TSTOP to XSPICE 2026-07-08 22:43:50 +02:00
Holger Vogt 1caee7903e Improve the error messages when reading a state file.
Bail out when the read has not been successfull.
2026-07-08 22:43:42 +02:00
Holger Vogt 9a79af8a3e Add MODEDCTRANCURVE to enable returning capacitance upon dc sweep.
Exclude integration if MODEDCTRANCURVE is active (forward,
self-heat and reverse diode)..
2026-07-08 22:43:26 +02:00
Holger Vogt e073718c0e Add MODEDCTRANCURVE to enable returning capacitance upon dc sweep.
Exclude integration if MODEDCTRANCURVE is active.
2026-07-08 22:43:19 +02:00
Holger Vogt 95414ec09b No integration, if dc sweep is to return cpacitances 2026-07-08 22:43:08 +02:00
Holger Vogt 08f2541d34 Reset ckt->CKTag[0] and ckt->CKTag[1] upon successful return
from transient simulation.
2026-07-08 22:43:02 +02:00
Holger Vogt 72620328a1 Excluded integration during self-heating as well. 2026-06-01 19:48:50 +02:00
Holger Vogt d029ed02db Diode: No integration if dc sweep, but keep calculating capacitances 2026-06-01 11:02:45 +02:00