40#include <wx/stdpaths.h>
59 m_ngSpice_Init( nullptr ),
60 m_ngSpice_Circ( nullptr ),
61 m_ngSpice_Command( nullptr ),
62 m_ngGet_Vec_Info( nullptr ),
63 m_ngCM_Input_Path( nullptr ),
64 m_ngSpice_CurPlot( nullptr ),
65 m_ngSpice_AllPlots( nullptr ),
66 m_ngSpice_AllVecs( nullptr ),
67 m_ngSpice_Running( nullptr ),
68 m_ngSpice_LockRealloc( nullptr ),
69 m_ngSpice_UnlockRealloc( nullptr ),
83 wxLogTrace(
traceNgspice,
"Sending Ngspice configuration command '%s'.", command );
109 std::vector<std::string> retVal;
111 if( allVectors !=
nullptr )
113 for(
char**
plot = allVectors; *
plot !=
nullptr;
plot++ )
116 retVal.reserve( noOfVectors );
118 for(
int i = 0; i < noOfVectors; i++, allVectors++ )
120 std::string vec = *allVectors;
121 retVal.push_back( std::move( vec ) );
133 std::vector<COMPLEX> data;
141 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
142 data.reserve( length );
146 for(
int i = 0; i < length; i++ )
147 data.emplace_back( vi->v_realdata[i], 0.0 );
149 else if( vi->v_compdata )
151 for(
int i = 0; i < length; i++ )
152 data.emplace_back( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag );
163 std::vector<double> data;
171 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
172 data.reserve( length );
176 for(
int i = 0; i < length; i++ )
177 data.push_back( vi->v_realdata[i] );
179 else if( vi->v_compdata )
181 for(
int i = 0; i < length; i++ )
182 data.push_back( vi->v_compdata[i].cx_real );
193 std::vector<double> data;
201 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
202 data.reserve( length );
206 for(
int i = 0; i < length; i++ )
207 data.push_back( vi->v_compdata[i].cx_imag );
218 std::vector<double> data;
226 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
227 data.reserve( length );
231 for(
int i = 0; i < length; i++ )
232 data.push_back( vi->v_realdata[i] );
234 else if( vi->v_compdata )
236 for(
int i = 0; i < length; i++ )
237 data.push_back( hypot( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag ) );
248 std::vector<double> data;
256 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
257 data.reserve( length );
261 for(
int i = 0; i < length; i++ )
262 data.push_back( 0.0 );
264 else if( vi->v_compdata )
266 for(
int i = 0; i < length; i++ )
267 data.push_back( atan2( vi->v_compdata[i].cx_imag, vi->v_compdata[i].cx_real ) );
275bool NGSPICE::Attach(
const std::shared_ptr<SIMULATION_MODEL>& aModel,
const wxString& aSimCommand,
276 unsigned aSimOptions,
const wxString& aInputPath,
REPORTER& aReporter )
283 if( model && model->
GetNetlist( aSimCommand, aSimOptions, &formatter, aReporter ) )
291 Command(
"echo Command: esave none" );
308 std::vector<char*> lines;
309 std::stringstream ss( aNetlist );
313 for( std::string line; std::getline( ss, line ); )
315 lines.push_back( strdup( line.data() ) );
320 lines.push_back(
nullptr );
325 for(
char* line : lines )
369 return wxS(
"frequency" );
375 if( vector.Lower().EndsWith( wxS(
"-sweep" ) ) )
379 return wxS(
"sweep" );
382 return wxS(
"time" );
385 return wxEmptyString;
394 std::vector<std::string> commands;
396 wxCHECK( settings, commands );
400 case NGSPICE_COMPATIBILITY_MODE::USER_CONFIG:
break;
401 case NGSPICE_COMPATIBILITY_MODE::NGSPICE: commands.emplace_back(
"unset ngbehavior" );
break;
402 case NGSPICE_COMPATIBILITY_MODE::PSPICE: commands.emplace_back(
"set ngbehavior=psa" );
break;
403 case NGSPICE_COMPATIBILITY_MODE::LTSPICE: commands.emplace_back(
"set ngbehavior=lta" );
break;
404 case NGSPICE_COMPATIBILITY_MODE::LT_PSPICE: commands.emplace_back(
"set ngbehavior=ltpsa" );
break;
405 case NGSPICE_COMPATIBILITY_MODE::HSPICE: commands.emplace_back(
"set ngbehavior=hsa" );
break;
406 default: wxFAIL_MSG( wxString::Format(
"Undefined NGSPICE_COMPATIBILITY_MODE %d.",
426 const wxStandardPaths& stdPaths = wxStandardPaths::Get();
428 if(
m_dll.IsLoaded() )
433 wxFileName dllFile(
"", NGSPICE_DLL_FILE );
434#if defined(__WINDOWS__)
435 #if defined( _MSC_VER )
436 std::vector<std::string> dllPaths = {
"" };
438 std::vector<std::string> dllPaths = {
"",
"/mingw64/bin",
"/mingw32/bin" };
440#elif defined(__WXMAC__)
441 std::vector<std::string> dllPaths = {
442 PATHS::GetOSXKicadUserDataDir().ToStdString() +
"/PlugIns/ngspice",
443 PATHS::GetOSXKicadMachineDataDir().ToStdString() +
"/PlugIns/ngspice",
446 stdPaths.GetPluginsDir().ToStdString() +
"/sim",
449 wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
450 "/../../../../../Contents/PlugIns/sim"
453 std::vector<std::string> dllPaths = {
"/usr/local/lib" };
456 if( wxGetEnv( wxT(
"KICAD_RUN_FROM_BUILD_DIR" ),
nullptr ) )
457 dllPaths.emplace_back( NGSPICE_DLL_DIR );
459#if defined(__WINDOWS__) || (__WXMAC__)
460 for(
const auto&
path : dllPaths )
462 dllFile.SetPath(
path );
463 wxLogTrace(
traceNgspice,
"libngspice search path: %s", dllFile.GetFullPath() );
464 m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
466 if(
m_dll.IsLoaded() )
468 wxLogTrace(
traceNgspice,
"libngspice path found in: %s", dllFile.GetFullPath() );
473 if( !
m_dll.IsLoaded() )
474 m_dll.Load( wxDynamicLibrary::CanonicalizeName(
"ngspice" ) );
477 m_dll.Load( NGSPICE_DLL_FILE, wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
480 if( !
m_dll.IsLoaded() )
482 for(
const auto&
path : dllPaths )
484 dllFile.SetPath(
path );
485 wxLogTrace(
traceNgspice,
"libngspice search path: %s", dllFile.GetFullPath() );
486 m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
488 if(
m_dll.IsLoaded() )
490 wxLogTrace(
traceNgspice,
"libngspice path found in: %s", dllFile.GetFullPath() );
497 if( !
m_dll.IsLoaded() )
498 throw std::runtime_error(
_(
"Unable to load ngspice shared library. Please check your install." ).ToStdString() );
513 if(
m_dll.HasSymbol(
"ngSpice_LockRealloc" ) )
524 wxString cwd( wxGetCwd() );
525 wxFileName exeDir( stdPaths.GetExecutablePath() );
526 wxSetWorkingDirectory( exeDir.GetPath() );
532 if( !cmPath.empty() )
533 Command(
"set __CMPATH=\"" + cmPath +
"\"" );
536 const std::vector<std::string> spiceinitPaths =
540 stdPaths.GetPluginsDir().ToStdString() +
"/sim/ngspice/scripts",
541 wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
542 "/../../../../../Contents/PlugIns/sim/ngspice/scripts"
550 bool foundSpiceinit =
false;
552 for(
const auto&
path : spiceinitPaths )
559 foundSpiceinit =
true;
566 if( !foundSpiceinit && !cmPath.empty() )
570 wxSetWorkingDirectory( cwd );
583 std::vector<char*> lines;
584 lines.push_back( strdup(
"*" ) );
585 lines.push_back( strdup(
".end" ) );
586 lines.push_back(
nullptr );
590 for(
auto line : lines )
599 if( !wxFileName::FileExists( aFileName ) )
604 if( !file.Open( aFileName ) )
607 for( wxString& cmd = file.GetFirstLine(); !file.Eof(); cmd = file.GetNextLine() )
616 const std::vector<std::string> cmPaths =
619 "/Applications/ngspice/lib/ngspice",
620 "Contents/Frameworks",
621 wxStandardPaths::Get().GetPluginsDir().ToStdString() +
"/sim/ngspice",
622 wxFileName( wxStandardPaths::Get().GetExecutablePath() ).GetPath().ToStdString() +
623 "/../../../../../Contents/PlugIns/sim/ngspice",
624 "../Plugins/sim/ngspice",
626 "../eeschema/ngspice",
633 for(
const auto&
path : cmPaths )
637 if( wxFileName::FileExists(
path +
"/spice2poly.cm" ) )
644 return std::string();
663 wxArrayString cmFiles;
664 size_t count = wxDir::GetAllFiles( aPath, &cmFiles );
666 for(
const auto& cm : cmFiles )
667 Command( fmt::format(
"codemodel '{}'", cm.ToStdString() ) );
680 if( ( strncasecmp( aWhat,
"stdout ", 7 ) == 0 )
681 || ( strncasecmp( aWhat,
"stderr ", 7 ) == 0 ) )
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Execute commands from a file.
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.
ngSpice_Circ m_ngSpice_Circ
bool Command(const std::string &aCmd) override final
Set a SIMULATOR_REPORTER object to receive the simulation log.
char **(* ngSpice_AllVecs)(char *plotname)
ngSpice_AllPlots m_ngSpice_AllPlots
static int cbControlledExit(int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId, void *aUser)
int(* ngSpice_Circ)(char **circarray)
ngSpice_UnlockRealloc m_ngSpice_UnlockRealloc
char **(* ngSpice_AllPlots)(void)
bool IsRunning() override final
Execute a Spice command as if it was typed into console.
std::vector< double > GetImaginaryVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with magnitude values.
virtual const std::string GetNetlist() const override final
Cleans simulation data (i.e.
char *(* ngSpice_CurPlot)(void)
ngSpice_Init m_ngSpice_Init
void updateNgspiceSettings()
Check a few different locations for codemodel files and returns one if it exists.
ngSpice_Command m_ngSpice_Command
int(* ngSpice_LockRealloc)(void)
void(* ngSpice_Init)(SendChar *, SendStat *, ControlledExit *, SendData *, SendInitData *, BGThreadRunning *, void *)
bool setCodemodelsInputPath(const std::string &aPath)
Load codemodel files from a directory.
wxString GetXAxis(SIM_TYPE aType) const override final
wxString CurrentPlotName() const override final
ngGet_Vec_Info m_ngGet_Vec_Info
bool m_error
Error flag indicating that ngspice needs to be reloaded.
ngCM_Input_Path m_ngCM_Input_Path
std::vector< double > GetPhaseVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with phase values.
ngSpice_LockRealloc m_ngSpice_LockRealloc
ngSpice_CurPlot m_ngSpice_CurPlot
bool loadSpinit(const std::string &aFileName)
bool Run() override final
Halt the simulation.
bool LoadNetlist(const std::string &aNetlist) override final
Execute the simulation with currently loaded netlist.
static int cbBGThreadRunning(NG_BOOL aFinished, int aId, void *aUser)
std::vector< double > GetGainVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with phase values.
bool Stop() override final
Check if simulation is running at the moment.
int(* ngSpice_Command)(char *command)
static bool m_initialized
Ngspice should be initialized only once.
static int cbSendStat(char *what, int aId, void *aUser)
static int cbSendChar(char *what, int aId, void *aUser)
std::vector< double > GetRealVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with imaginary values.
char *(* ngCM_Input_Path)(const char *path)
std::vector< std::string > GetSettingCommands() const override final
Return current SPICE netlist used by the simulator.
std::string m_netlist
Current netlist.
ngSpice_AllVecs m_ngSpice_AllVecs
int(* ngSpice_UnlockRealloc)(void)
Handle to DLL functions.
pvector_info(* ngGet_Vec_Info)(char *vecname)
ngSpice_Running m_ngSpice_Running
void Clean() override final
Cleans simulation data (i.e.
bool(* ngSpice_Running)(void)
void Init(const SPICE_SETTINGS *aSettings=nullptr) override final
Point out the model that will be used in future simulations.
bool Attach(const std::shared_ptr< SIMULATION_MODEL > &aModel, const wxString &aSimCommand, unsigned aSimOptions, const wxString &aInputPath, REPORTER &aReporter) override final
Load a netlist for the simulation.
std::string findCmPath() const
Send additional search path for codemodels to ngspice.
bool loadCodemodels(const std::string &aPath)
std::vector< COMPLEX > GetComplexVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with real values.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
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, const wxString &aInputPath, REPORTER &aReporter)
Point out the model that will be used in future simulations.
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.
static const wxChar *const traceNgspice
Flag to enable debug output of Ngspice simulator.
SIM_TYPE
< Possible simulation types