diff --git a/eeschema/sim/ngspice.cpp b/eeschema/sim/ngspice.cpp index 2c4bfc5cc5..26d9ebb262 100644 --- a/eeschema/sim/ngspice.cpp +++ b/eeschema/sim/ngspice.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016-2022 CERN - * Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2018-2024 KiCad Developers, see AUTHORS.txt for contributors. * * @author Tomasz Wlostowski * @author Maciej Suminski @@ -59,6 +59,7 @@ NGSPICE::NGSPICE() : m_ngSpice_Circ( nullptr ), m_ngSpice_Command( nullptr ), m_ngGet_Vec_Info( nullptr ), + m_ngCM_Input_Path( nullptr ), m_ngSpice_CurPlot( nullptr ), m_ngSpice_AllPlots( nullptr ), m_ngSpice_AllVecs( nullptr ), @@ -274,21 +275,23 @@ std::vector NGSPICE::GetPhaseVector( const std::string& aName, int aMaxL bool NGSPICE::Attach( const std::shared_ptr& aModel, const wxString& aSimCommand, - unsigned aSimOptions, REPORTER& aReporter ) + unsigned aSimOptions, const wxString& aInputPath, REPORTER& aReporter ) { SPICE_CIRCUIT_MODEL* model = dynamic_cast( aModel.get() ); STRING_FORMATTER formatter; + setCodemodelsInputPath( aInputPath.ToStdString() ); + if( model && model->GetNetlist( aSimCommand, aSimOptions, &formatter, aReporter ) ) { - SIMULATOR::Attach( aModel, aSimCommand, aSimOptions, aReporter ); + SIMULATOR::Attach( aModel, aSimCommand, aSimOptions, aInputPath, aReporter ); updateNgspiceSettings(); LoadNetlist( formatter.GetString() ); return true; } else { - SIMULATOR::Attach( nullptr, wxEmptyString, 0, aReporter ); + SIMULATOR::Attach( nullptr, wxEmptyString, 0, wxEmptyString, aReporter ); return false; } } @@ -494,6 +497,7 @@ void NGSPICE::init_dll() m_ngSpice_Circ = (ngSpice_Circ) m_dll.GetSymbol( "ngSpice_Circ" ); m_ngSpice_Command = (ngSpice_Command) m_dll.GetSymbol( "ngSpice_Command" ); m_ngGet_Vec_Info = (ngGet_Vec_Info) m_dll.GetSymbol( "ngGet_Vec_Info" ); + m_ngCM_Input_Path = (ngCM_Input_Path) m_dll.GetSymbol( "ngCM_Input_Path" ); m_ngSpice_CurPlot = (ngSpice_CurPlot) m_dll.GetSymbol( "ngSpice_CurPlot" ); m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll.GetSymbol( "ngSpice_AllPlots" ); m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll.GetSymbol( "ngSpice_AllVecs" ); @@ -634,6 +638,19 @@ std::string NGSPICE::findCmPath() const } +bool NGSPICE::setCodemodelsInputPath( const std::string& aPath ) +{ + if( !m_ngCM_Input_Path ) + return false; + + LOCALE_IO c_locale; // ngspice works correctly only with C locale + + m_ngCM_Input_Path( aPath.c_str() ); + + return true; +} + + bool NGSPICE::loadCodemodels( const std::string& aPath ) { wxArrayString cmFiles; diff --git a/eeschema/sim/ngspice.h b/eeschema/sim/ngspice.h index fdde8c4d16..464caf5c4a 100644 --- a/eeschema/sim/ngspice.h +++ b/eeschema/sim/ngspice.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016-2022 CERN - * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors. * * @author Tomasz Wlostowski * @@ -60,7 +60,8 @@ public: ///< @copydoc SPICE_SIMULATOR::Attach() bool Attach( const std::shared_ptr& aModel, const wxString& aSimCommand, - unsigned aSimOptions, REPORTER& aReporter ) override final; + unsigned aSimOptions, const wxString& aInputPath, + REPORTER& aReporter ) override final; ///< Load a netlist for the simulation bool LoadNetlist( const std::string& aNetlist ) override final; @@ -116,21 +117,24 @@ private: // ngspice library functions typedef void ( *ngSpice_Init )( SendChar*, SendStat*, ControlledExit*, SendData*, SendInitData*, BGThreadRunning*, void* ); - typedef int ( *ngSpice_Circ )( char** circarray ); - typedef int ( *ngSpice_Command )( char* command ); + + typedef int ( *ngSpice_Circ )( char** circarray ); + typedef int ( *ngSpice_Command )( char* command ); typedef pvector_info ( *ngGet_Vec_Info )( char* vecname ); - typedef char* ( *ngSpice_CurPlot )( void ); - typedef char** ( *ngSpice_AllPlots )( void ); - typedef char** ( *ngSpice_AllVecs )( char* plotname ); - typedef bool ( *ngSpice_Running )( void ); - typedef int ( *ngSpice_LockRealloc )( void ); - typedef int ( *ngSpice_UnlockRealloc )( void ); + typedef char* ( *ngCM_Input_Path )( const char* path ); + typedef char* ( *ngSpice_CurPlot )( void ); + typedef char** ( *ngSpice_AllPlots )( void ); + typedef char** ( *ngSpice_AllVecs )( char* plotname ); + typedef bool ( *ngSpice_Running )( void ); + typedef int ( *ngSpice_LockRealloc )( void ); + typedef int ( *ngSpice_UnlockRealloc )( void ); ///< Handle to DLL functions ngSpice_Init m_ngSpice_Init; ngSpice_Circ m_ngSpice_Circ; ngSpice_Command m_ngSpice_Command; ngGet_Vec_Info m_ngGet_Vec_Info; + ngCM_Input_Path m_ngCM_Input_Path; ngSpice_CurPlot m_ngSpice_CurPlot; ngSpice_AllPlots m_ngSpice_AllPlots; ngSpice_AllVecs m_ngSpice_AllVecs; @@ -168,6 +172,9 @@ private: ///< Check a few different locations for codemodel files and returns one if it exists. std::string findCmPath() const; + ///< Send additional search path for codemodels to ngspice. + bool setCodemodelsInputPath( const std::string& aPath ); + ///< Load codemodel files from a directory. bool loadCodemodels( const std::string& aPath ); diff --git a/eeschema/sim/simulator.h b/eeschema/sim/simulator.h index 8ff88ea48d..5116747252 100644 --- a/eeschema/sim/simulator.h +++ b/eeschema/sim/simulator.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2022 Sylwester Kocjan - * Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2022-2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -59,7 +59,8 @@ public: * @return True in case of success, false otherwise. */ virtual bool Attach( const std::shared_ptr& aModel, - const wxString& aSimCommand, unsigned aSimOptions, REPORTER& aReporter ) + const wxString& aSimCommand, unsigned aSimOptions, + const wxString& aInputPath, REPORTER& aReporter ) { m_simModel = aModel; return true; @@ -87,8 +88,8 @@ public: virtual bool IsRunning() = 0; /** - * Cleans simulation data (i.e. all vectors) - * + * Cleans simulation data (i.e. all vectors) + * */ virtual void Clean() = 0; diff --git a/eeschema/sim/simulator_frame.cpp b/eeschema/sim/simulator_frame.cpp index effa700029..39bf4038d0 100644 --- a/eeschema/sim/simulator_frame.cpp +++ b/eeschema/sim/simulator_frame.cpp @@ -194,7 +194,7 @@ SIMULATOR_FRAME::~SIMULATOR_FRAME() { NULL_REPORTER devnull; - m_simulator->Attach( nullptr, wxEmptyString, 0, devnull ); + m_simulator->Attach( nullptr, wxEmptyString, 0, wxEmptyString, devnull ); m_simulator->SetReporter( nullptr ); delete m_reporter; } @@ -358,7 +358,8 @@ bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimO if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity ) m_schematicFrame->RecalculateConnections( nullptr, GLOBAL_CLEANUP ); - if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, reporter ) ) + if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, Prj().GetProjectPath(), + reporter ) ) { DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + errors ); return false; @@ -373,7 +374,8 @@ void SIMULATOR_FRAME::ReloadSimulator( const wxString& aSimCommand, unsigned aSi wxString errors; WX_STRING_REPORTER reporter( &errors ); - if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, reporter ) ) + if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, Prj().GetProjectPath(), + reporter ) ) { DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + errors ); }