Send project path to ngspice for code model input files.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16527

(cherry picked from commit eb7e781bec)
This commit is contained in:
Alex Shvartzkop 2024-05-08 23:39:23 +03:00
parent a99377c1ec
commit 81281f7e74
4 changed files with 48 additions and 21 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016-2022 CERN * 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 <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
@ -59,6 +59,7 @@ NGSPICE::NGSPICE() :
m_ngSpice_Circ( nullptr ), m_ngSpice_Circ( nullptr ),
m_ngSpice_Command( nullptr ), m_ngSpice_Command( nullptr ),
m_ngGet_Vec_Info( nullptr ), m_ngGet_Vec_Info( nullptr ),
m_ngCM_Input_Path( nullptr ),
m_ngSpice_CurPlot( nullptr ), m_ngSpice_CurPlot( nullptr ),
m_ngSpice_AllPlots( nullptr ), m_ngSpice_AllPlots( nullptr ),
m_ngSpice_AllVecs( nullptr ), m_ngSpice_AllVecs( nullptr ),
@ -274,21 +275,23 @@ std::vector<double> NGSPICE::GetPhaseVector( const std::string& aName, int aMaxL
bool NGSPICE::Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, const wxString& aSimCommand, bool NGSPICE::Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, const wxString& aSimCommand,
unsigned aSimOptions, REPORTER& aReporter ) unsigned aSimOptions, const wxString& aInputPath, REPORTER& aReporter )
{ {
SPICE_CIRCUIT_MODEL* model = dynamic_cast<SPICE_CIRCUIT_MODEL*>( aModel.get() ); SPICE_CIRCUIT_MODEL* model = dynamic_cast<SPICE_CIRCUIT_MODEL*>( aModel.get() );
STRING_FORMATTER formatter; STRING_FORMATTER formatter;
setCodemodelsInputPath( aInputPath.ToStdString() );
if( model && model->GetNetlist( aSimCommand, aSimOptions, &formatter, aReporter ) ) if( model && model->GetNetlist( aSimCommand, aSimOptions, &formatter, aReporter ) )
{ {
SIMULATOR::Attach( aModel, aSimCommand, aSimOptions, aReporter ); SIMULATOR::Attach( aModel, aSimCommand, aSimOptions, aInputPath, aReporter );
updateNgspiceSettings(); updateNgspiceSettings();
LoadNetlist( formatter.GetString() ); LoadNetlist( formatter.GetString() );
return true; return true;
} }
else else
{ {
SIMULATOR::Attach( nullptr, wxEmptyString, 0, aReporter ); SIMULATOR::Attach( nullptr, wxEmptyString, 0, wxEmptyString, aReporter );
return false; return false;
} }
} }
@ -494,6 +497,7 @@ void NGSPICE::init_dll()
m_ngSpice_Circ = (ngSpice_Circ) m_dll.GetSymbol( "ngSpice_Circ" ); m_ngSpice_Circ = (ngSpice_Circ) m_dll.GetSymbol( "ngSpice_Circ" );
m_ngSpice_Command = (ngSpice_Command) m_dll.GetSymbol( "ngSpice_Command" ); m_ngSpice_Command = (ngSpice_Command) m_dll.GetSymbol( "ngSpice_Command" );
m_ngGet_Vec_Info = (ngGet_Vec_Info) m_dll.GetSymbol( "ngGet_Vec_Info" ); 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_CurPlot = (ngSpice_CurPlot) m_dll.GetSymbol( "ngSpice_CurPlot" );
m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll.GetSymbol( "ngSpice_AllPlots" ); m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll.GetSymbol( "ngSpice_AllPlots" );
m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll.GetSymbol( "ngSpice_AllVecs" ); 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 ) bool NGSPICE::loadCodemodels( const std::string& aPath )
{ {
wxArrayString cmFiles; wxArrayString cmFiles;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016-2022 CERN * 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 <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
@ -60,7 +60,8 @@ public:
///< @copydoc SPICE_SIMULATOR::Attach() ///< @copydoc SPICE_SIMULATOR::Attach()
bool Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, const wxString& aSimCommand, bool Attach( const std::shared_ptr<SIMULATION_MODEL>& 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 ///< Load a netlist for the simulation
bool LoadNetlist( const std::string& aNetlist ) override final; bool LoadNetlist( const std::string& aNetlist ) override final;
@ -116,21 +117,24 @@ private:
// ngspice library functions // ngspice library functions
typedef void ( *ngSpice_Init )( SendChar*, SendStat*, ControlledExit*, SendData*, SendInitData*, typedef void ( *ngSpice_Init )( SendChar*, SendStat*, ControlledExit*, SendData*, SendInitData*,
BGThreadRunning*, void* ); 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 pvector_info ( *ngGet_Vec_Info )( char* vecname );
typedef char* ( *ngSpice_CurPlot )( void ); typedef char* ( *ngCM_Input_Path )( const char* path );
typedef char** ( *ngSpice_AllPlots )( void ); typedef char* ( *ngSpice_CurPlot )( void );
typedef char** ( *ngSpice_AllVecs )( char* plotname ); typedef char** ( *ngSpice_AllPlots )( void );
typedef bool ( *ngSpice_Running )( void ); typedef char** ( *ngSpice_AllVecs )( char* plotname );
typedef int ( *ngSpice_LockRealloc )( void ); typedef bool ( *ngSpice_Running )( void );
typedef int ( *ngSpice_UnlockRealloc )( void ); typedef int ( *ngSpice_LockRealloc )( void );
typedef int ( *ngSpice_UnlockRealloc )( void );
///< Handle to DLL functions ///< Handle to DLL functions
ngSpice_Init m_ngSpice_Init; ngSpice_Init m_ngSpice_Init;
ngSpice_Circ m_ngSpice_Circ; ngSpice_Circ m_ngSpice_Circ;
ngSpice_Command m_ngSpice_Command; ngSpice_Command m_ngSpice_Command;
ngGet_Vec_Info m_ngGet_Vec_Info; ngGet_Vec_Info m_ngGet_Vec_Info;
ngCM_Input_Path m_ngCM_Input_Path;
ngSpice_CurPlot m_ngSpice_CurPlot; ngSpice_CurPlot m_ngSpice_CurPlot;
ngSpice_AllPlots m_ngSpice_AllPlots; ngSpice_AllPlots m_ngSpice_AllPlots;
ngSpice_AllVecs m_ngSpice_AllVecs; ngSpice_AllVecs m_ngSpice_AllVecs;
@ -168,6 +172,9 @@ private:
///< Check a few different locations for codemodel files and returns one if it exists. ///< Check a few different locations for codemodel files and returns one if it exists.
std::string findCmPath() const; std::string findCmPath() const;
///< Send additional search path for codemodels to ngspice.
bool setCodemodelsInputPath( const std::string& aPath );
///< Load codemodel files from a directory. ///< Load codemodel files from a directory.
bool loadCodemodels( const std::string& aPath ); bool loadCodemodels( const std::string& aPath );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2022 Sylwester Kocjan <s.kocjan@o2.pl> * Copyright (C) 2022 Sylwester Kocjan <s.kocjan@o2.pl>
* 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 * 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 * 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. * @return True in case of success, false otherwise.
*/ */
virtual bool Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, virtual bool Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel,
const wxString& aSimCommand, unsigned aSimOptions, REPORTER& aReporter ) const wxString& aSimCommand, unsigned aSimOptions,
const wxString& aInputPath, REPORTER& aReporter )
{ {
m_simModel = aModel; m_simModel = aModel;
return true; return true;
@ -87,8 +88,8 @@ public:
virtual bool IsRunning() = 0; virtual bool IsRunning() = 0;
/** /**
* Cleans simulation data (i.e. all vectors) * Cleans simulation data (i.e. all vectors)
* *
*/ */
virtual void Clean() = 0; virtual void Clean() = 0;

View File

@ -194,7 +194,7 @@ SIMULATOR_FRAME::~SIMULATOR_FRAME()
{ {
NULL_REPORTER devnull; NULL_REPORTER devnull;
m_simulator->Attach( nullptr, wxEmptyString, 0, devnull ); m_simulator->Attach( nullptr, wxEmptyString, 0, wxEmptyString, devnull );
m_simulator->SetReporter( nullptr ); m_simulator->SetReporter( nullptr );
delete m_reporter; delete m_reporter;
} }
@ -358,7 +358,8 @@ bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimO
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity ) if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
m_schematicFrame->RecalculateConnections( nullptr, GLOBAL_CLEANUP ); 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 ); DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + errors );
return false; return false;
@ -373,7 +374,8 @@ void SIMULATOR_FRAME::ReloadSimulator( const wxString& aSimCommand, unsigned aSi
wxString errors; wxString errors;
WX_STRING_REPORTER reporter( &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 ); DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + errors );
} }