40 #include <wx/stdpaths.h> 61 m_ngSpice_Init( nullptr ),
62 m_ngSpice_Circ( nullptr ),
63 m_ngSpice_Command( nullptr ),
64 m_ngGet_Vec_Info( nullptr ),
65 m_ngSpice_CurPlot( nullptr ),
66 m_ngSpice_AllPlots( nullptr ),
67 m_ngSpice_AllVecs( nullptr ),
68 m_ngSpice_Running( nullptr ),
86 wxLogTrace(
traceNgspice, wxT(
"Sending Ngspice configuration command '%s'." ), command );
99 vector<string> retVal;
101 if( allPlots !=
nullptr )
106 retVal.reserve( noOfPlots );
108 for(
int i = 0; i < noOfPlots; i++, allPlots++ )
110 string vec = *allPlots;
111 retVal.push_back( vec );
123 vector<COMPLEX> data;
128 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
129 data.reserve( length );
133 for(
int i = 0; i < length; i++ )
134 data.emplace_back( vi->v_realdata[i], 0.0 );
136 else if( vi->v_compdata )
138 for(
int i = 0; i < length; i++ )
139 data.emplace_back( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag );
155 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
156 data.reserve( length );
160 for(
int i = 0; i < length; i++ )
162 data.push_back( vi->v_realdata[i] );
165 else if( vi->v_compdata )
167 for(
int i = 0; i < length; i++ )
169 wxASSERT( vi->v_compdata[i].cx_imag == 0.0 );
170 data.push_back( vi->v_compdata[i].cx_real );
187 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
188 data.reserve( length );
192 for(
int i = 0; i < length; i++ )
194 data.push_back( vi->v_compdata[i].cx_imag );
211 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
212 data.reserve( length );
216 for(
int i = 0; i < length; i++ )
217 data.push_back( vi->v_realdata[i] );
219 else if( vi->v_compdata )
221 for(
int i = 0; i < length; i++ )
222 data.push_back( hypot( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag ) );
238 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
239 data.reserve( length );
243 for(
int i = 0; i < length; i++ )
244 data.push_back( 0.0 );
246 else if( vi->v_compdata )
248 for(
int i = 0; i < length; i++ )
249 data.push_back( atan2( vi->v_compdata[i].cx_imag, vi->v_compdata[i].cx_real ) );
261 stringstream ss( aNetlist );
268 ss.getline( line,
sizeof( line ) );
269 lines.push_back( strdup( line ) );
270 m_netlist += std::string( line ) + std::string(
"\n" );
273 lines.push_back(
nullptr );
276 for(
auto line : lines )
288 bool success =
Command(
"bg_run" );
336 return string(
"frequency" );
342 const string sweepEnding =
"-sweep";
343 unsigned int len = sweepEnding.length();
345 if(
plot.length() > len
346 &&
plot.substr(
plot.length() - len, len ).compare( sweepEnding ) == 0 )
348 return string(
plot );
354 return string(
"time" );
367 dynamic_cast<const NGSPICE_SIMULATOR_SETTINGS*>(
Settings().get() );
369 std::vector<std::string> commands;
371 wxCHECK( settings, commands );
379 commands.emplace_back(
"unset ngbehavior" );
383 commands.emplace_back(
"set ngbehavior=ps" );
387 commands.emplace_back(
"set ngbehavior=lt" );
391 commands.emplace_back(
"set ngbehavior=ltps" );
395 commands.emplace_back(
"set ngbehavior=hs" );
420 const wxStandardPaths& stdPaths = wxStandardPaths::Get();
422 if(
m_dll.IsLoaded() )
427 wxFileName dllFile(
"", NGSPICE_DLL_FILE );
428 #if defined(__WINDOWS__) 429 #if defined( _MSC_VER ) 430 const vector<string> dllPaths = {
"" };
432 const vector<string> dllPaths = {
"",
"/mingw64/bin",
"/mingw32/bin" };
434 #elif defined(__WXMAC__) 435 const vector<string> dllPaths = {
436 PATHS::GetOSXKicadUserDataDir().ToStdString() +
"/PlugIns/ngspice",
437 PATHS::GetOSXKicadMachineDataDir().ToStdString() +
"/PlugIns/ngspice",
440 stdPaths.GetPluginsDir().ToStdString() +
"/sim",
443 wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
444 "/../../../../../Contents/PlugIns/sim" 446 #else // Unix systems 447 const vector<string> dllPaths = {
"/usr/local/lib" };
450 #if defined(__WINDOWS__) || (__WXMAC__) 451 for(
const auto&
path : dllPaths )
453 dllFile.SetPath(
path );
454 wxLogTrace(
traceNgspice, wxT(
"libngspice search path: %s" ), dllFile.GetFullPath() );
455 m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
457 if(
m_dll.IsLoaded() )
459 wxLogTrace(
traceNgspice, wxT(
"libngspice path found in: %s" ), dllFile.GetFullPath() );
464 if( !
m_dll.IsLoaded() )
465 m_dll.Load( wxDynamicLibrary::CanonicalizeName( wxT(
"ngspice" ) ) );
468 m_dll.Load( NGSPICE_DLL_FILE, wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
471 if( !
m_dll.IsLoaded() )
473 for(
const auto&
path : dllPaths )
475 dllFile.SetPath(
path );
476 wxLogTrace(
traceNgspice, wxT(
"libngspice search path: %s" ), dllFile.GetFullPath() );
477 m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
479 if(
m_dll.IsLoaded() )
481 wxLogTrace(
traceNgspice, wxT(
"libngspice path found in: %s" ), dllFile.GetFullPath() );
488 if( !
m_dll.IsLoaded() )
489 throw std::runtime_error(
"Missing ngspice shared library" );
508 wxString cwd( wxGetCwd() );
509 wxFileName exeDir( stdPaths.GetExecutablePath() );
510 wxSetWorkingDirectory( exeDir.GetPath() );
516 if( !cmPath.empty() )
517 Command(
"set __CMPATH=\"" + cmPath +
"\"" );
520 const vector<string> spiceinitPaths =
524 stdPaths.GetPluginsDir().ToStdString() +
"/sim/ngspice/scripts",
525 wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
526 "/../../../../../Contents/PlugIns/sim/ngspice/scripts" 534 bool foundSpiceinit =
false;
536 for(
const auto&
path : spiceinitPaths )
538 wxLogTrace(
traceNgspice, wxT(
"ngspice init script search path: %s" ),
path );
543 foundSpiceinit =
true;
550 if( !foundSpiceinit && !cmPath.empty() )
554 wxSetWorkingDirectory( cwd );
558 Command(
"unset interactive" );
568 if( !wxFileName::FileExists( aFileName ) )
573 if( !file.Open( aFileName ) )
576 for(
auto cmd = file.GetFirstLine(); !file.Eof(); cmd = file.GetNextLine() )
585 const vector<string> cmPaths =
588 "/Applications/ngspice/lib/ngspice",
589 "Contents/Frameworks",
590 wxStandardPaths::Get().GetPluginsDir().ToStdString() +
"/sim/ngspice",
591 wxFileName( wxStandardPaths::Get().GetExecutablePath() ).GetPath().ToStdString() +
592 "/../../../../../Contents/PlugIns/sim/ngspice",
593 "../Plugins/sim/ngspice",
601 for(
const auto&
path : cmPaths )
603 wxLogTrace(
traceNgspice, wxT(
"ngspice code models search path: %s" ),
path );
605 if( wxFileName::FileExists(
path + wxT(
"/spice2poly.cm" ) ) )
607 wxLogTrace(
traceNgspice, wxT(
"ngspice code models found in: %s" ),
path );
618 wxArrayString cmFiles;
619 size_t count = wxDir::GetAllFiles( aPath, &cmFiles );
621 for(
const auto& cm : cmFiles )
622 Command(
"codemodel " + cm.ToStdString() );
630 NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
635 if( ( strncasecmp( aWhat,
"stdout ", 7 ) == 0 )
636 || ( strncasecmp( aWhat,
"stderr ", 7 ) == 0 ) )
654 NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
666 NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
std::vector< std::string > AllPlots() const override
Return a requested vector with complex values.
static int cbBGThreadRunning(NG_BOOL aFinished, int aId, void *aUser)
bool Run() override
Halt the simulation.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
void validate()
Error flag indicating that ngspice needs to be reloaded.
static const wxChar *const traceNgspice
Flag to enable debug output of Ngspice simulator.
std::string findCmPath() const
Load codemodel files from a directory.
SPICE_REPORTER * m_reporter
< Reporter object to receive simulation log.
std::shared_ptr< SPICE_SIMULATOR_SETTINGS > & Settings()
Return the simulator configuration settings.
std::vector< double > GetRealPlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with imaginary values.
char **(* ngSpice_AllVecs)(char *plotname)
wxDynamicLibrary m_dll
Execute commands from a file.
bool loadCodemodels(const std::string &aPath)
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
std::vector< double > GetImagPlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with magnitude values.
ngSpice_Running m_ngSpice_Running
std::vector< double > GetMagPlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with phase values.
static bool m_initialized
Current netlist.
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
void(* ngSpice_Init)(SendChar *, SendStat *, ControlledExit *, SendData *, SendInitData *, BGThreadRunning *, void *)
virtual const std::string GetNetlist() const override
Return current SPICE netlist used by the simulator.
ngGet_Vec_Info m_ngGet_Vec_Info
bool m_error
Ngspice should be initialized only once.
SIM_TYPE
< Possible simulation types
pvector_info(* ngGet_Vec_Info)(char *vecname)
char *(* ngSpice_CurPlot)(void)
std::vector< COMPLEX > GetPlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with real values.
bool Stop() override
Check if simulation is running at the moment.
ngSpice_Init m_ngSpice_Init
std::string GetXAxis(SIM_TYPE aType) const override
Return a list with all vectors generated in current simulation.
std::vector< double > GetPhasePlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with phase values.
int(* ngSpice_Command)(char *command)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
void Init(const SPICE_SIMULATOR_SETTINGS *aSettings=nullptr) override
Load a netlist for the simulation.
NGSPICE_MODEL_MODE GetModelMode() const
bool LoadNetlist(const std::string &aNetlist) override
Execute the simulation with currently loaded netlist.
bool(* ngSpice_Running)(void)
Handle to DLL functions.
Container for Ngspice simulator settings.
static int cbControlledExit(int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId, void *aUser)
bool Command(const std::string &aCmd) override
Set a SPICE_REPORTER object to receive the simulation log.
static int cbSendStat(char *what, int aId, void *aUser)
bool IsRunning() override
Execute a Spice command as if it was typed into console.
ngSpice_AllVecs m_ngSpice_AllVecs
std::vector< std::string > GetSettingCommands() const override
Return current SPICE netlist used by the simulator.
virtual void OnSimStateChange(SPICE_SIMULATOR *aObject, SIM_STATE aNewState)=0
ngSpice_Command m_ngSpice_Command
bool loadSpinit(const std::string &aFileName)
Check a few different locations for codemodel files and returns one if it exists.
static int cbSendChar(char *what, int aId, void *aUser)
ngSpice_Circ m_ngSpice_Circ
ngSpice_CurPlot m_ngSpice_CurPlot
ngSpice_AllPlots m_ngSpice_AllPlots
char **(* ngSpice_AllPlots)(void)
int(* ngSpice_Circ)(char **circarray)
Storage for simulator specific settings.