KiCad PCB EDA Suite
Loading...
Searching...
No Matches
ngspice.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2016-2022 CERN
5 * Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Tomasz Wlostowski <[email protected]>
8 * @author Maciej Suminski <[email protected]>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 3
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, you may find one here:
22 * https://www.gnu.org/licenses/gpl-3.0.html
23 * or you may search the http://www.gnu.org website for the version 3 license,
24 * or you may write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 */
27
28#include <config.h> // Needed for MSW compilation
29#include <common.h>
30#include <locale_io.h>
31#include <fmt/core.h>
32#include <paths.h>
33
34#include "spice_circuit_model.h"
35#include "ngspice.h"
36#include "simulator_reporter.h"
37#include "spice_settings.h"
38
39#include <wx/stdpaths.h>
40#include <wx/dir.h>
41#include <wx/log.h>
42
43#include <stdexcept>
44#include <algorithm>
45
46
54static const wxChar* const traceNgspice = wxT( "KICAD_NGSPICE" );
55
56
58 m_ngSpice_Init( nullptr ),
59 m_ngSpice_Circ( nullptr ),
60 m_ngSpice_Command( nullptr ),
61 m_ngGet_Vec_Info( nullptr ),
62 m_ngSpice_CurPlot( nullptr ),
63 m_ngSpice_AllPlots( nullptr ),
64 m_ngSpice_AllVecs( nullptr ),
65 m_ngSpice_Running( nullptr ),
66 m_ngSpice_LockRealloc( nullptr ),
67 m_ngSpice_UnlockRealloc( nullptr ),
68 m_error( false )
69{
70 init_dll();
71}
72
73
74NGSPICE::~NGSPICE() = default;
75
76
78{
79 for( const std::string& command : GetSettingCommands() )
80 {
81 wxLogTrace( traceNgspice, "Sending Ngspice configuration command '%s'.", command );
82 Command( command );
83 }
84}
85
86
87void NGSPICE::Init( const SPICE_SETTINGS* aSettings )
88{
89 Command( "reset" );
91}
92
93
95{
96 return wxString( m_ngSpice_CurPlot() );
97}
98
99
100std::vector<std::string> NGSPICE::AllVectors() const
101{
102 LOCALE_IO c_locale; // ngspice works correctly only with C locale
103 char* currentPlot = m_ngSpice_CurPlot();
104 char** allVectors = m_ngSpice_AllVecs( currentPlot );
105 int noOfVectors = 0;
106
107 std::vector<std::string> retVal;
108
109 if( allVectors != nullptr )
110 {
111 for( char** plot = allVectors; *plot != nullptr; plot++ )
112 noOfVectors++;
113
114 retVal.reserve( noOfVectors );
115
116 for( int i = 0; i < noOfVectors; i++, allVectors++ )
117 {
118 std::string vec = *allVectors;
119 retVal.push_back( vec );
120 }
121 }
122
123
124 return retVal;
125}
126
127
128std::vector<COMPLEX> NGSPICE::GetComplexVector( const std::string& aName, int aMaxLen )
129{
130 LOCALE_IO c_locale; // ngspice works correctly only with C locale
131 std::vector<COMPLEX> data;
132 NGSPICE_LOCK_REALLOC lock( this );
133
134 if( aMaxLen == 0 )
135 return data;
136
137 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
138 {
139 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
140 data.reserve( length );
141
142 if( vi->v_realdata )
143 {
144 for( int i = 0; i < length; i++ )
145 data.emplace_back( vi->v_realdata[i], 0.0 );
146 }
147 else if( vi->v_compdata )
148 {
149 for( int i = 0; i < length; i++ )
150 data.emplace_back( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag );
151 }
152 }
153
154 return data;
155}
156
157
158std::vector<double> NGSPICE::GetRealVector( const std::string& aName, int aMaxLen )
159{
160 LOCALE_IO c_locale; // ngspice works correctly only with C locale
161 std::vector<double> data;
162 NGSPICE_LOCK_REALLOC lock( this );
163
164 if( aMaxLen == 0 )
165 return data;
166
167 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
168 {
169 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
170 data.reserve( length );
171
172 if( vi->v_realdata )
173 {
174 for( int i = 0; i < length; i++ )
175 data.push_back( vi->v_realdata[i] );
176 }
177 else if( vi->v_compdata )
178 {
179 for( int i = 0; i < length; i++ )
180 {
181 wxASSERT( vi->v_compdata[i].cx_imag == 0.0 );
182 data.push_back( vi->v_compdata[i].cx_real );
183 }
184 }
185 }
186
187 return data;
188}
189
190
191std::vector<double> NGSPICE::GetImaginaryVector( const std::string& aName, int aMaxLen )
192{
193 LOCALE_IO c_locale; // ngspice works correctly only with C locale
194 std::vector<double> data;
195 NGSPICE_LOCK_REALLOC lock( this );
196
197 if( aMaxLen == 0 )
198 return data;
199
200 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
201 {
202 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
203 data.reserve( length );
204
205 if( vi->v_compdata )
206 {
207 for( int i = 0; i < length; i++ )
208 data.push_back( vi->v_compdata[i].cx_imag );
209 }
210 }
211
212 return data;
213}
214
215
216std::vector<double> NGSPICE::GetGainVector( const std::string& aName, int aMaxLen )
217{
218 LOCALE_IO c_locale; // ngspice works correctly only with C locale
219 std::vector<double> data;
220 NGSPICE_LOCK_REALLOC lock( this );
221
222 if( aMaxLen == 0 )
223 return data;
224
225 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
226 {
227 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
228 data.reserve( length );
229
230 if( vi->v_realdata )
231 {
232 for( int i = 0; i < length; i++ )
233 data.push_back( vi->v_realdata[i] );
234 }
235 else if( vi->v_compdata )
236 {
237 for( int i = 0; i < length; i++ )
238 data.push_back( hypot( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag ) );
239 }
240 }
241
242 return data;
243}
244
245
246std::vector<double> NGSPICE::GetPhaseVector( const std::string& aName, int aMaxLen )
247{
248 LOCALE_IO c_locale; // ngspice works correctly only with C locale
249 std::vector<double> data;
250 NGSPICE_LOCK_REALLOC lock( this );
251
252 if( aMaxLen == 0 )
253 return data;
254
255 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
256 {
257 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
258 data.reserve( length );
259
260 if( vi->v_realdata )
261 {
262 for( int i = 0; i < length; i++ )
263 data.push_back( 0.0 ); // well, that's life
264 }
265 else if( vi->v_compdata )
266 {
267 for( int i = 0; i < length; i++ )
268 data.push_back( atan2( vi->v_compdata[i].cx_imag, vi->v_compdata[i].cx_real ) );
269 }
270 }
271
272 return data;
273}
274
275
276bool NGSPICE::Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, const wxString& aSimCommand,
277 unsigned aSimOptions, REPORTER& aReporter )
278{
279 SPICE_CIRCUIT_MODEL* model = dynamic_cast<SPICE_CIRCUIT_MODEL*>( aModel.get() );
280 STRING_FORMATTER formatter;
281
282 if( model && model->GetNetlist( aSimCommand, aSimOptions, &formatter, aReporter ) )
283 {
284 SIMULATOR::Attach( aModel, aSimCommand, aSimOptions, aReporter );
286 LoadNetlist( formatter.GetString() );
287 return true;
288 }
289 else
290 {
291 SIMULATOR::Attach( nullptr, wxEmptyString, 0, aReporter );
292 return false;
293 }
294}
295
296
297bool NGSPICE::LoadNetlist( const std::string& aNetlist )
298{
299 LOCALE_IO c_locale; // ngspice works correctly only with C locale
300 std::vector<char*> lines;
301 std::stringstream ss( aNetlist );
302
303 m_netlist = "";
304
305 while( !ss.eof() )
306 {
307 char line[1024];
308 ss.getline( line, sizeof( line ) );
309 lines.push_back( strdup( line ) );
310 m_netlist += std::string( line ) + std::string( "\n" );
311 }
312
313 lines.push_back( nullptr ); // sentinel, as requested in ngSpice_Circ description
314
315 Command( "remcirc" );
316 bool success = !m_ngSpice_Circ( lines.data() );
317
318 for( char* line : lines )
319 free( line );
320
321 return success;
322}
323
324
326{
327 LOCALE_IO toggle; // ngspice works correctly only with C locale
328 return Command( "bg_run" ); // bg_* commands execute in a separate thread
329}
330
331
333{
334 LOCALE_IO c_locale; // ngspice works correctly only with C locale
335 return Command( "bg_halt" ); // bg_* commands execute in a separate thread
336}
337
338
340{
341 // No need to use C locale here
342 return m_ngSpice_Running();
343}
344
345
346bool NGSPICE::Command( const std::string& aCmd )
347{
348 LOCALE_IO c_locale; // ngspice works correctly only with C locale
349 validate();
350 return !m_ngSpice_Command( (char*) aCmd.c_str() );
351}
352
353
354wxString NGSPICE::GetXAxis( SIM_TYPE aType ) const
355{
356 switch( aType )
357 {
358 case ST_AC:
359 case ST_SP:
360 case ST_NOISE:
361 case ST_FFT:
362 return wxS( "frequency" );
363
364 case ST_DC:
365 // find plot, which ends with "-sweep"
366 for( wxString vector : AllVectors() )
367 {
368 if( vector.Lower().EndsWith( wxS( "-sweep" ) ) )
369 return vector;
370 }
371
372 return wxS( "sweep" );
373
374 case ST_TRAN:
375 return wxS( "time" );
376
377 default:
378 return wxEmptyString;
379 }
380}
381
382
383std::vector<std::string> NGSPICE::GetSettingCommands() const
384{
385 const NGSPICE_SETTINGS* settings = dynamic_cast<const NGSPICE_SETTINGS*>( Settings().get() );
386
387 std::vector<std::string> commands;
388
389 wxCHECK( settings, commands );
390
391 switch( settings->GetCompatibilityMode() )
392 {
393 case NGSPICE_COMPATIBILITY_MODE::USER_CONFIG: break;
394 case NGSPICE_COMPATIBILITY_MODE::NGSPICE: commands.emplace_back( "unset ngbehavior" ); break;
395 case NGSPICE_COMPATIBILITY_MODE::PSPICE: commands.emplace_back( "set ngbehavior=psa" ); break;
396 case NGSPICE_COMPATIBILITY_MODE::LTSPICE: commands.emplace_back( "set ngbehavior=lta" ); break;
397 case NGSPICE_COMPATIBILITY_MODE::LT_PSPICE: commands.emplace_back( "set ngbehavior=ltpsa" ); break;
398 case NGSPICE_COMPATIBILITY_MODE::HSPICE: commands.emplace_back( "set ngbehavior=hsa" ); break;
399 default: wxFAIL_MSG( wxString::Format( "Undefined NGSPICE_COMPATIBILITY_MODE %d.",
400 settings->GetCompatibilityMode() ) ); break;
401 }
402
403 return commands;
404}
405
406
407const std::string NGSPICE::GetNetlist() const
408{
409 return m_netlist;
410}
411
412
414{
415 if( m_initialized )
416 return;
417
418 LOCALE_IO c_locale; // ngspice works correctly only with C locale
419 const wxStandardPaths& stdPaths = wxStandardPaths::Get();
420
421 if( m_dll.IsLoaded() ) // enable force reload
422 m_dll.Unload();
423
424 // Extra effort to find libngspice
425 // @todo Shouldn't we be using the normal KiCad path searching mechanism here?
426 wxFileName dllFile( "", NGSPICE_DLL_FILE );
427#if defined(__WINDOWS__)
428 #if defined( _MSC_VER )
429 const std::vector<std::string> dllPaths = { "" };
430 #else
431 const std::vector<std::string> dllPaths = { "", "/mingw64/bin", "/mingw32/bin" };
432 #endif
433#elif defined(__WXMAC__)
434 const std::vector<std::string> dllPaths = {
435 PATHS::GetOSXKicadUserDataDir().ToStdString() + "/PlugIns/ngspice",
436 PATHS::GetOSXKicadMachineDataDir().ToStdString() + "/PlugIns/ngspice",
437
438 // when running kicad.app
439 stdPaths.GetPluginsDir().ToStdString() + "/sim",
440
441 // when running eeschema.app
442 wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
443 "/../../../../../Contents/PlugIns/sim"
444 };
445#else // Unix systems
446 const std::vector<std::string> dllPaths = { "/usr/local/lib" };
447#endif
448
449#if defined(__WINDOWS__) || (__WXMAC__)
450 for( const auto& path : dllPaths )
451 {
452 dllFile.SetPath( path );
453 wxLogTrace( traceNgspice, "libngspice search path: %s", dllFile.GetFullPath() );
454 m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
455
456 if( m_dll.IsLoaded() )
457 {
458 wxLogTrace( traceNgspice, "libngspice path found in: %s", dllFile.GetFullPath() );
459 break;
460 }
461 }
462
463 if( !m_dll.IsLoaded() ) // try also the system libraries
464 m_dll.Load( wxDynamicLibrary::CanonicalizeName( "ngspice" ) );
465#else
466 // First, try the system libraries
467 m_dll.Load( NGSPICE_DLL_FILE, wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
468
469 // If failed, try some other paths:
470 if( !m_dll.IsLoaded() )
471 {
472 for( const auto& path : dllPaths )
473 {
474 dllFile.SetPath( path );
475 wxLogTrace( traceNgspice, "libngspice search path: %s", dllFile.GetFullPath() );
476 m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
477
478 if( m_dll.IsLoaded() )
479 {
480 wxLogTrace( traceNgspice, "libngspice path found in: %s", dllFile.GetFullPath() );
481 break;
482 }
483 }
484 }
485#endif
486
487 if( !m_dll.IsLoaded() )
488 throw std::runtime_error( "Missing ngspice shared library" );
489
490 m_error = false;
491
492 // Obtain function pointers
493 m_ngSpice_Init = (ngSpice_Init) m_dll.GetSymbol( "ngSpice_Init" );
494 m_ngSpice_Circ = (ngSpice_Circ) m_dll.GetSymbol( "ngSpice_Circ" );
495 m_ngSpice_Command = (ngSpice_Command) m_dll.GetSymbol( "ngSpice_Command" );
496 m_ngGet_Vec_Info = (ngGet_Vec_Info) m_dll.GetSymbol( "ngGet_Vec_Info" );
497 m_ngSpice_CurPlot = (ngSpice_CurPlot) m_dll.GetSymbol( "ngSpice_CurPlot" );
498 m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll.GetSymbol( "ngSpice_AllPlots" );
499 m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll.GetSymbol( "ngSpice_AllVecs" );
500 m_ngSpice_Running = (ngSpice_Running) m_dll.GetSymbol( "ngSpice_running" ); // it is not a typo
501
502 if( m_dll.HasSymbol( "ngSpice_LockRealloc" ) )
503 {
504 m_ngSpice_LockRealloc = (ngSpice_LockRealloc) m_dll.GetSymbol( "ngSpice_LockRealloc" );
505 m_ngSpice_UnlockRealloc = (ngSpice_UnlockRealloc) m_dll.GetSymbol( "ngSpice_UnlockRealloc" );
506 }
507
509 &cbBGThreadRunning, this );
510
511 // Load a custom spinit file, to fix the problem with loading .cm files
512 // Switch to the executable directory, so the relative paths are correct
513 wxString cwd( wxGetCwd() );
514 wxFileName exeDir( stdPaths.GetExecutablePath() );
515 wxSetWorkingDirectory( exeDir.GetPath() );
516
517 // Find *.cm files
518 std::string cmPath = findCmPath();
519
520 // __CMPATH is used in custom spinit file to point to the codemodels directory
521 if( !cmPath.empty() )
522 Command( "set __CMPATH=\"" + cmPath + "\"" );
523
524 // Possible relative locations for spinit file
525 const std::vector<std::string> spiceinitPaths =
526 {
527 ".",
528#ifdef __WXMAC__
529 stdPaths.GetPluginsDir().ToStdString() + "/sim/ngspice/scripts",
530 wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
531 "/../../../../../Contents/PlugIns/sim/ngspice/scripts"
532#endif
533 "../share/kicad",
534 "../share",
535 "../../share/kicad",
536 "../../share"
537 };
538
539 bool foundSpiceinit = false;
540
541 for( const auto& path : spiceinitPaths )
542 {
543 wxLogTrace( traceNgspice, "ngspice init script search path: %s", path );
544
545 if( loadSpinit( path + "/spiceinit" ) )
546 {
547 wxLogTrace( traceNgspice, "ngspice path found in: %s", path );
548 foundSpiceinit = true;
549 break;
550 }
551 }
552
553 // Last chance to load codemodel files, we have not found
554 // spiceinit file, but we know the path to *.cm files
555 if( !foundSpiceinit && !cmPath.empty() )
556 loadCodemodels( cmPath );
557
558 // Restore the working directory
559 wxSetWorkingDirectory( cwd );
560
561 // Workarounds to avoid hang ups on certain errors
562 // These commands have to be called, no matter what is in the spinit file
563 // We have to allow interactive for user-defined signals. Hopefully whatever bug this was
564 // meant to address has gone away in the last 5 years...
565 //Command( "unset interactive" );
566 Command( "set noaskquit" );
567 Command( "set nomoremode" );
568
569 // reset and remcirc give an error if no circuit is loaded, so load an empty circuit at the
570 // start.
571
572 std::vector<char*> lines;
573 lines.push_back( strdup( "*" ) );
574 lines.push_back( strdup( ".end" ) );
575 lines.push_back( nullptr ); // Sentinel.
576
577 m_ngSpice_Circ( lines.data() );
578
579 for( auto line : lines )
580 free( line );
581
582 m_initialized = true;
583}
584
585
586bool NGSPICE::loadSpinit( const std::string& aFileName )
587{
588 if( !wxFileName::FileExists( aFileName ) )
589 return false;
590
591 wxTextFile file;
592
593 if( !file.Open( aFileName ) )
594 return false;
595
596 for( wxString& cmd = file.GetFirstLine(); !file.Eof(); cmd = file.GetNextLine() )
597 Command( cmd.ToStdString() );
598
599 return true;
600}
601
602
603std::string NGSPICE::findCmPath() const
604{
605 const std::vector<std::string> cmPaths =
606 {
607#ifdef __WXMAC__
608 "/Applications/ngspice/lib/ngspice",
609 "Contents/Frameworks",
610 wxStandardPaths::Get().GetPluginsDir().ToStdString() + "/sim/ngspice",
611 wxFileName( wxStandardPaths::Get().GetExecutablePath() ).GetPath().ToStdString() +
612 "/../../../../../Contents/PlugIns/sim/ngspice",
613 "../Plugins/sim/ngspice",
614#endif
615 "../eeschema/ngspice",
616 "../lib/ngspice",
617 "../../lib/ngspice",
618 "lib/ngspice",
619 "ngspice"
620 };
621
622 for( const auto& path : cmPaths )
623 {
624 wxLogTrace( traceNgspice, "ngspice code models search path: %s", path );
625
626 if( wxFileName::FileExists( path + "/spice2poly.cm" ) )
627 {
628 wxLogTrace( traceNgspice, "ngspice code models found in: %s", path );
629 return path;
630 }
631 }
632
633 return std::string();
634}
635
636
637bool NGSPICE::loadCodemodels( const std::string& aPath )
638{
639 wxArrayString cmFiles;
640 size_t count = wxDir::GetAllFiles( aPath, &cmFiles );
641
642 for( const auto& cm : cmFiles )
643 Command( fmt::format( "codemodel '{}'", cm.ToStdString() ) );
644
645 return count != 0;
646}
647
648
649int NGSPICE::cbSendChar( char* aWhat, int aId, void* aUser )
650{
651 NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
652
653 if( sim->m_reporter )
654 {
655 // strip stdout/stderr from the line
656 if( ( strncasecmp( aWhat, "stdout ", 7 ) == 0 )
657 || ( strncasecmp( aWhat, "stderr ", 7 ) == 0 ) )
658 {
659 aWhat += 7;
660 }
661
662 sim->m_reporter->Report( aWhat );
663 }
664
665 return 0;
666}
667
668
669int NGSPICE::cbSendStat( char *aWhat, int aId, void* aUser )
670{
671 return 0;
672}
673
674
675int NGSPICE::cbBGThreadRunning( NG_BOOL aFinished, int aId, void* aUser )
676{
677 NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
678
679 if( sim->m_reporter )
680 sim->m_reporter->OnSimStateChange( sim, aFinished ? SIM_IDLE : SIM_RUNNING );
681
682 return 0;
683}
684
685
686int NGSPICE::cbControlledExit( int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId,
687 void* aUser )
688{
689 // Something went wrong, reload the dll
690 NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
691 sim->m_error = true;
692
693 return 0;
694}
695
696
698{
699 if( m_error )
700 {
701 m_initialized = false;
702 init_dll();
703 }
704}
705
706
708{
709 Command( "destroy all" );
710}
711
712
713bool NGSPICE::m_initialized = false;
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
Execute commands from a file.
Definition: ngspice.h:144
Container for Ngspice simulator settings.
NGSPICE_COMPATIBILITY_MODE GetCompatibilityMode() const
std::vector< std::string > AllVectors() const override final
Return a requested vector with complex values.
Definition: ngspice.cpp:100
ngSpice_Circ m_ngSpice_Circ
Definition: ngspice.h:131
bool Command(const std::string &aCmd) override final
Set a SIMULATOR_REPORTER object to receive the simulation log.
Definition: ngspice.cpp:346
char **(* ngSpice_AllVecs)(char *plotname)
Definition: ngspice.h:124
ngSpice_AllPlots m_ngSpice_AllPlots
Definition: ngspice.h:135
static int cbControlledExit(int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId, void *aUser)
Definition: ngspice.cpp:686
int(* ngSpice_Circ)(char **circarray)
Definition: ngspice.h:119
ngSpice_UnlockRealloc m_ngSpice_UnlockRealloc
Definition: ngspice.h:139
char **(* ngSpice_AllPlots)(void)
Definition: ngspice.h:123
bool IsRunning() override final
Execute a Spice command as if it was typed into console.
Definition: ngspice.cpp:339
std::vector< double > GetImaginaryVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with magnitude values.
Definition: ngspice.cpp:191
virtual const std::string GetNetlist() const override final
Cleans simulation data (i.e.
Definition: ngspice.cpp:407
char *(* ngSpice_CurPlot)(void)
Definition: ngspice.h:122
ngSpice_Init m_ngSpice_Init
Definition: ngspice.h:130
void updateNgspiceSettings()
Check a few different locations for codemodel files and returns one if it exists.
Definition: ngspice.cpp:77
ngSpice_Command m_ngSpice_Command
Definition: ngspice.h:132
int(* ngSpice_LockRealloc)(void)
Definition: ngspice.h:126
void(* ngSpice_Init)(SendChar *, SendStat *, ControlledExit *, SendData *, SendInitData *, BGThreadRunning *, void *)
Definition: ngspice.h:117
wxString GetXAxis(SIM_TYPE aType) const override final
Definition: ngspice.cpp:354
wxString CurrentPlotName() const override final
Definition: ngspice.cpp:94
ngGet_Vec_Info m_ngGet_Vec_Info
Definition: ngspice.h:133
bool m_error
Error flag indicating that ngspice needs to be reloaded.
Definition: ngspice.h:185
std::vector< double > GetPhaseVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with phase values.
Definition: ngspice.cpp:246
virtual ~NGSPICE()
ngSpice_LockRealloc m_ngSpice_LockRealloc
Definition: ngspice.h:138
ngSpice_CurPlot m_ngSpice_CurPlot
Definition: ngspice.h:134
void init_dll()
Definition: ngspice.cpp:413
bool loadSpinit(const std::string &aFileName)
Definition: ngspice.cpp:586
bool Run() override final
Halt the simulation.
Definition: ngspice.cpp:325
bool LoadNetlist(const std::string &aNetlist) override final
Execute the simulation with currently loaded netlist.
Definition: ngspice.cpp:297
static int cbBGThreadRunning(NG_BOOL aFinished, int aId, void *aUser)
Definition: ngspice.cpp:675
std::vector< double > GetGainVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with phase values.
Definition: ngspice.cpp:216
bool Stop() override final
Check if simulation is running at the moment.
Definition: ngspice.cpp:332
int(* ngSpice_Command)(char *command)
Definition: ngspice.h:120
static bool m_initialized
Ngspice should be initialized only once.
Definition: ngspice.h:187
static int cbSendStat(char *what, int aId, void *aUser)
Definition: ngspice.cpp:669
static int cbSendChar(char *what, int aId, void *aUser)
Definition: ngspice.cpp:649
std::vector< double > GetRealVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with imaginary values.
Definition: ngspice.cpp:158
std::vector< std::string > GetSettingCommands() const override final
Return current SPICE netlist used by the simulator.
Definition: ngspice.cpp:383
std::string m_netlist
Current netlist.
Definition: ngspice.h:189
ngSpice_AllVecs m_ngSpice_AllVecs
Definition: ngspice.h:136
int(* ngSpice_UnlockRealloc)(void)
Handle to DLL functions.
Definition: ngspice.h:127
pvector_info(* ngGet_Vec_Info)(char *vecname)
Definition: ngspice.h:121
ngSpice_Running m_ngSpice_Running
Definition: ngspice.h:137
void Clean() override final
Cleans simulation data (i.e.
Definition: ngspice.cpp:707
bool(* ngSpice_Running)(void)
Definition: ngspice.h:125
wxDynamicLibrary m_dll
Definition: ngspice.h:141
NGSPICE()
Definition: ngspice.cpp:57
void Init(const SPICE_SETTINGS *aSettings=nullptr) override final
Point out the model that will be used in future simulations.
Definition: ngspice.cpp:87
void validate()
Definition: ngspice.cpp:697
bool Attach(const std::shared_ptr< SIMULATION_MODEL > &aModel, const wxString &aSimCommand, unsigned aSimOptions, REPORTER &aReporter) override final
Load a netlist for the simulation.
Definition: ngspice.cpp:276
std::string findCmPath() const
Load codemodel files from a directory.
Definition: ngspice.cpp:603
bool loadCodemodels(const std::string &aPath)
Definition: ngspice.cpp:637
std::vector< COMPLEX > GetComplexVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with real values.
Definition: ngspice.cpp:128
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:71
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
virtual void OnSimStateChange(SIMULATOR *aObject, SIM_STATE aNewState)=0
virtual bool Attach(const std::shared_ptr< SIMULATION_MODEL > &aModel, const wxString &aSimCommand, unsigned aSimOptions, REPORTER &aReporter)
Point out the model that will be used in future simulations.
Definition: simulator.h:61
Special netlist exporter flavor that allows one to override simulation commands.
bool GetNetlist(const wxString &aCommand, unsigned aOptions, OUTPUTFORMATTER *aFormatter, REPORTER &aReporter)
Storage for simulator specific settings.
std::shared_ptr< SPICE_SETTINGS > & Settings()
Return the simulator configuration settings.
SIMULATOR_REPORTER * m_reporter
< Reporter object to receive simulation log.
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:433
const std::string & GetString()
Definition: richio.h:456
The common library.
static const wxChar *const traceNgspice
Flag to enable debug output of Ngspice simulator.
Definition: ngspice.cpp:54
bool NG_BOOL
Definition: ngspice.h:46
SIM_TYPE
< Possible simulation types
Definition: sim_types.h:32
@ ST_SP
Definition: sim_types.h:43
@ ST_TRAN
Definition: sim_types.h:42
@ ST_NOISE
Definition: sim_types.h:37
@ ST_AC
Definition: sim_types.h:34
@ ST_DC
Definition: sim_types.h:35
@ ST_FFT
Definition: sim_types.h:44
@ SIM_IDLE
@ SIM_RUNNING