You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
7.0 KiB

3 years ago
3 years ago
3 years ago
3 years ago
  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 The KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 3
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * https://www.gnu.org/licenses/gpl-3.0.html
  22. * or you may search the http://www.gnu.org website for the version 3 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. #ifndef NGSPICE_H
  27. #define NGSPICE_H
  28. #include <sim/spice_simulator.h>
  29. #include <sim/sim_model.h>
  30. #include <sim/sim_value.h>
  31. #include <wx/dynlib.h>
  32. #include <ngspice/sharedspice.h>
  33. #include <enum_vector.h>
  34. // We have an issue here where NGSPICE incorrectly used bool for years
  35. // and defined it to be int when in C-mode. We cannot adjust the function
  36. // signatures without re-writing sharedspice.h for KiCad.
  37. // Instead, we maintain status-quo for older NGSPICE versions (<=34) and
  38. // use the new signatures for newer versions
  39. #ifndef NGSPICE_PACKAGE_VERSION
  40. typedef bool NG_BOOL;
  41. #endif
  42. class wxDynamicLibrary;
  43. class NGSPICE : public SPICE_SIMULATOR
  44. {
  45. public:
  46. NGSPICE();
  47. virtual ~NGSPICE();
  48. ///< @copydoc SPICE_SIMULATOR::Init()
  49. void Init( const SPICE_SETTINGS* aSettings = nullptr ) override final;
  50. ///< @copydoc SPICE_SIMULATOR::Attach()
  51. bool Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, const wxString& aSimCommand,
  52. unsigned aSimOptions, const wxString& aInputPath,
  53. REPORTER& aReporter ) override final;
  54. ///< Load a netlist for the simulation
  55. bool LoadNetlist( const std::string& aNetlist ) override final;
  56. ///< @copydoc SPICE_SIMULATOR::Run()
  57. bool Run() override final;
  58. ///< @copydoc SPICE_SIMULATOR::Stop()
  59. bool Stop() override final;
  60. ///< @copydoc SPICE_SIMULATOR::IsRunning()
  61. bool IsRunning() override final;
  62. ///< @copydoc SPICE_SIMULATOR::Command()
  63. bool Command( const std::string& aCmd ) override final;
  64. ///< @copydoc SPICE_SIMULATOR::GetXAxis()
  65. wxString GetXAxis( SIM_TYPE aType ) const override final;
  66. ///< @copydoc SPICE_SIMULATOR::CurrentPlotName()
  67. wxString CurrentPlotName() const override final;
  68. ///< @copydoc SPICE_SIMULATOR::AllVectors()
  69. std::vector<std::string> AllVectors() const override final;
  70. ///< @copydoc SPICE_SIMULATOR::GetComplexVector()
  71. std::vector<COMPLEX> GetComplexVector( const std::string& aName, int aMaxLen = -1 ) override final;
  72. ///< @copydoc SPICE_SIMULATOR::GetRealVector()
  73. std::vector<double> GetRealVector( const std::string& aName, int aMaxLen = -1 ) override final;
  74. ///< @copydoc SPICE_SIMULATOR::GetImaginaryVector()
  75. std::vector<double> GetImaginaryVector( const std::string& aName, int aMaxLen = -1 ) override final;
  76. ///< @copydoc SPICE_SIMULATOR::GetGainVector()
  77. std::vector<double> GetGainVector( const std::string& aName, int aMaxLen = -1 ) override final;
  78. ///< @copydoc SPICE_SIMULATOR::GetPhaseVector()
  79. std::vector<double> GetPhaseVector( const std::string& aName, int aMaxLen = -1 ) override final;
  80. std::vector<std::string> GetSettingCommands() const override final;
  81. ///< @copydoc SPICE_SIMULATOR::GetNetlist()
  82. virtual const std::string GetNetlist() const override final;
  83. ///< @copydoc SIMULATOR::Clean()
  84. void Clean() override final;
  85. private:
  86. // Performs DLL initialization, obtains function pointers
  87. void init_dll();
  88. // ngspice library functions
  89. typedef void ( *ngSpice_Init )( SendChar*, SendStat*, ControlledExit*, SendData*, SendInitData*,
  90. BGThreadRunning*, void* );
  91. typedef int ( *ngSpice_Circ )( char** circarray );
  92. typedef int ( *ngSpice_Command )( char* command );
  93. typedef pvector_info ( *ngGet_Vec_Info )( char* vecname );
  94. typedef char* ( *ngCM_Input_Path )( const char* path );
  95. typedef char* ( *ngSpice_CurPlot )( void );
  96. typedef char** ( *ngSpice_AllPlots )( void );
  97. typedef char** ( *ngSpice_AllVecs )( char* plotname );
  98. typedef bool ( *ngSpice_Running )( void );
  99. typedef int ( *ngSpice_LockRealloc )( void );
  100. typedef int ( *ngSpice_UnlockRealloc )( void );
  101. ///< Handle to DLL functions
  102. ngSpice_Init m_ngSpice_Init;
  103. ngSpice_Circ m_ngSpice_Circ;
  104. ngSpice_Command m_ngSpice_Command;
  105. ngGet_Vec_Info m_ngGet_Vec_Info;
  106. ngCM_Input_Path m_ngCM_Input_Path;
  107. ngSpice_CurPlot m_ngSpice_CurPlot;
  108. ngSpice_AllPlots m_ngSpice_AllPlots;
  109. ngSpice_AllVecs m_ngSpice_AllVecs;
  110. ngSpice_Running m_ngSpice_Running;
  111. ngSpice_LockRealloc m_ngSpice_LockRealloc;
  112. ngSpice_UnlockRealloc m_ngSpice_UnlockRealloc;
  113. wxDynamicLibrary m_dll;
  114. class NGSPICE_LOCK_REALLOC
  115. {
  116. public:
  117. NGSPICE_LOCK_REALLOC( NGSPICE* ngspice ) :
  118. m_ngspice( ngspice )
  119. {
  120. if( m_ngspice->m_ngSpice_LockRealloc )
  121. m_ngspice->m_ngSpice_LockRealloc();
  122. };
  123. ~NGSPICE_LOCK_REALLOC()
  124. {
  125. if( m_ngspice->m_ngSpice_UnlockRealloc )
  126. m_ngspice->m_ngSpice_UnlockRealloc();
  127. };
  128. private:
  129. NGSPICE* m_ngspice;
  130. };
  131. ///< Execute commands from a file
  132. bool loadSpinit( const std::string& aFileName );
  133. void updateNgspiceSettings();
  134. ///< Check a few different locations for codemodel files and returns one if it exists.
  135. std::string findCmPath() const;
  136. ///< Send additional search path for codemodels to ngspice.
  137. bool setCodemodelsInputPath( const std::string& aPath );
  138. ///< Load codemodel files from a directory.
  139. bool loadCodemodels( const std::string& aPath );
  140. // Callback functions
  141. static int cbSendChar( char* what, int aId, void* aUser );
  142. static int cbSendStat( char* what, int aId, void* aUser );
  143. static int cbBGThreadRunning( NG_BOOL aFinished, int aId, void* aUser );
  144. static int cbControlledExit( int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId,
  145. void* aUser );
  146. // Assure ngspice is in a valid state and reinitializes it if need be.
  147. void validate();
  148. private:
  149. bool m_error; ///< Error flag indicating that ngspice needs to be reloaded.
  150. static bool m_initialized; ///< Ngspice should be initialized only once.
  151. std::string m_netlist; ///< Current netlist
  152. };
  153. #endif /* NGSPICE_H */