eeschema,sim: add SIMULATOR and SIM_MODEL interface

SIMULATOR has now an Attach() method, which should be called
with proper SIMULATION_MODEL that should be simulated, before calling Run()

Concrete class of SIMULATION_MODEL for ngspice is NGSPICE_CIRCUIT_MODEL,
renamed from NETLIST_EXPORTER_PSPICE_SIM. DIALOG_SIM_SETTINGS relies
on above mentioned object, so it was added as an argument of the constructor.
This commit is contained in:
Sylwester Kocjan 2022-03-06 00:49:25 +01:00 committed by Mikolaj Wielgus
parent be6379a8f6
commit f5dedd77c6
19 changed files with 225 additions and 108 deletions

View File

@ -305,7 +305,7 @@ if( KICAD_SPICE )
dialogs/dialog_sim_settings_base.cpp
dialogs/dialog_spice_model.cpp
dialogs/dialog_spice_model_base.cpp
sim/netlist_exporter_pspice_sim.cpp
sim/ngspice_helpers.cpp
sim/ngspice.cpp
sim/sim_panel_base.cpp
sim/sim_plot_colors.cpp

View File

@ -28,11 +28,11 @@
#include <string_utils.h>
#include <sim/sim_plot_frame.h>
#include <sim/netlist_exporter_pspice_sim.h>
#include <sim/ngspice_helpers.h>
DIALOG_SIGNAL_LIST::DIALOG_SIGNAL_LIST( SIM_PLOT_FRAME* aParent,
NETLIST_EXPORTER_PSPICE_SIM* aExporter ) :
NGSPICE_CIRCUIT_MODEL* aExporter ) :
DIALOG_SIGNAL_LIST_BASE( aParent ),
m_plotFrame( aParent ),
m_exporter( aExporter )
@ -76,7 +76,7 @@ bool DIALOG_SIGNAL_LIST::TransferDataToWindow()
{
// Add all possible currents for the primitive
for( const auto& current :
NETLIST_EXPORTER_PSPICE_SIM::GetCurrents( (SPICE_PRIMITIVE) item.m_primitive ) )
NGSPICE_CIRCUIT_MODEL::GetCurrents( (SPICE_PRIMITIVE) item.m_primitive ) )
{
m_signals->Append( wxString::Format( "%s(%s)", current, item.m_refName ) );
}

View File

@ -28,12 +28,12 @@
#include "dialog_signal_list_base.h"
class SIM_PLOT_FRAME;
class NETLIST_EXPORTER_PSPICE_SIM;
class NGSPICE_CIRCUIT_MODEL;
class DIALOG_SIGNAL_LIST : public DIALOG_SIGNAL_LIST_BASE
{
public:
DIALOG_SIGNAL_LIST( SIM_PLOT_FRAME* aParent, NETLIST_EXPORTER_PSPICE_SIM* aExporter );
DIALOG_SIGNAL_LIST( SIM_PLOT_FRAME* aParent, NGSPICE_CIRCUIT_MODEL* aExporter );
bool TransferDataFromWindow() override;
bool TransferDataToWindow() override;
@ -48,7 +48,7 @@ private:
bool addSignalToPlotFrame( const wxString& aPlotName );
SIM_PLOT_FRAME* m_plotFrame;
NETLIST_EXPORTER_PSPICE_SIM* m_exporter;
NGSPICE_CIRCUIT_MODEL* m_exporter;
};
#endif /* DIALOG_SIGNAL_LIST_H */

View File

@ -24,7 +24,7 @@
*/
#include "dialog_sim_settings.h"
#include <sim/netlist_exporter_pspice_sim.h>
#include <sim/ngspice_helpers.h>
#include <sim/ngspice.h>
#include <confirm.h>
@ -57,7 +57,7 @@ static wxString getStringSelection( const wxChoice* aCtrl )
DIALOG_SIM_SETTINGS::DIALOG_SIM_SETTINGS( wxWindow* aParent,
std::shared_ptr<NETLIST_EXPORTER_PSPICE_SIM> aExporter,
std::shared_ptr<NGSPICE_CIRCUIT_MODEL> aExporter,
std::shared_ptr<SPICE_SIMULATOR_SETTINGS>& aSettings ) :
DIALOG_SIM_SETTINGS_BASE( aParent ),
m_exporter( aExporter ),

View File

@ -32,14 +32,14 @@
#include <wx/valnum.h>
class NETLIST_EXPORTER_PSPICE_SIM;
class NGSPICE_CIRCUIT_MODEL;
class SPICE_SIMULATOR_SETTINGS;
class DIALOG_SIM_SETTINGS : public DIALOG_SIM_SETTINGS_BASE
{
public:
DIALOG_SIM_SETTINGS( wxWindow* aParent, std::shared_ptr<NETLIST_EXPORTER_PSPICE_SIM> aExporter,
DIALOG_SIM_SETTINGS( wxWindow* aParent, std::shared_ptr<NGSPICE_CIRCUIT_MODEL> aExporter,
std::shared_ptr<SPICE_SIMULATOR_SETTINGS>& aSettings );
const wxString& GetSimCommand() const
@ -178,7 +178,7 @@ private:
wxString m_simCommand;
int m_netlistOpts;
std::shared_ptr<NETLIST_EXPORTER_PSPICE_SIM> m_exporter;
std::shared_ptr<NGSPICE_CIRCUIT_MODEL> m_exporter;
std::shared_ptr<SPICE_SIMULATOR_SETTINGS> m_settings;
SPICE_VALIDATOR m_spiceValidator;
SPICE_VALIDATOR m_spiceEmptyValidator;

View File

@ -28,6 +28,7 @@
#include <config.h> // Needed for MSW compilation
#include <wx/log.h>
#include "ngspice_helpers.h"
#include "ngspice.h"
#include "spice_reporter.h"
#include "spice_settings.h"
@ -254,6 +255,29 @@ vector<double> NGSPICE::GetPhasePlot( const string& aName, int aMaxLen )
}
bool NGSPICE::Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel )
{
NGSPICE_CIRCUIT_MODEL* model = dynamic_cast<NGSPICE_CIRCUIT_MODEL*>( aModel.get() );
wxASSERT( model != nullptr );
STRING_FORMATTER formatter;
if( model->GetNetlist( &formatter ) )
{
SIMULATOR::Attach( aModel );
LoadNetlist( formatter.GetString() );
return true;
}
else
{
SIMULATOR::Attach( nullptr );
return false;
}
}
bool NGSPICE::LoadNetlist( const string& aNetlist )
{
LOCALE_IO c_locale; // ngspice works correctly only with C locale
@ -271,6 +295,8 @@ bool NGSPICE::LoadNetlist( const string& aNetlist )
}
lines.push_back( nullptr ); // sentinel, as requested in ngSpice_Circ description
Command( "remcirc" );
m_ngSpice_Circ( lines.data() );
for( auto line : lines )

View File

@ -43,6 +43,7 @@
class wxDynamicLibrary;
class NGSPICE : public SPICE_SIMULATOR
{
public:
@ -50,48 +51,51 @@ public:
virtual ~NGSPICE();
///< @copydoc SPICE_SIMULATOR::Init()
void Init( const SPICE_SIMULATOR_SETTINGS* aSettings = nullptr ) override;
void Init( const SPICE_SIMULATOR_SETTINGS* aSettings = nullptr ) override final;
///< @copydoc SPICE_SIMULATOR::LoadNetlist()
bool LoadNetlist( const std::string& aNetlist ) override;
///< @copydoc SPICE_SIMULATOR::Attach()
bool Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel ) override final;
///< Load a netlist for the simulation
bool LoadNetlist( const std::string& aNetlist ) override final;
///< @copydoc SPICE_SIMULATOR::Run()
bool Run() override;
bool Run() override final;
///< @copydoc SPICE_SIMULATOR::Stop()
bool Stop() override;
bool Stop() override final;
///< @copydoc SPICE_SIMULATOR::IsRunning()
bool IsRunning() override;
bool IsRunning() override final;
///< @copydoc SPICE_SIMULATOR::Command()
bool Command( const std::string& aCmd ) override;
bool Command( const std::string& aCmd ) override final;
///< @copydoc SPICE_SIMULATOR::GetXAxis()
std::string GetXAxis( SIM_TYPE aType ) const override;
std::string GetXAxis( SIM_TYPE aType ) const override final;
///< @copydoc SPICE_SIMULATOR::AllPlots()
std::vector<std::string> AllPlots() const override;
std::vector<std::string> AllPlots() const override final;
///< @copydoc SPICE_SIMULATOR::GetPlot()
std::vector<COMPLEX> GetPlot( const std::string& aName, int aMaxLen = -1 ) override;
std::vector<COMPLEX> GetPlot( const std::string& aName, int aMaxLen = -1 ) override final;
///< @copydoc SPICE_SIMULATOR::GetRealPlot()
std::vector<double> GetRealPlot( const std::string& aName, int aMaxLen = -1 ) override;
std::vector<double> GetRealPlot( const std::string& aName, int aMaxLen = -1 ) override final;
///< @copydoc SPICE_SIMULATOR::GetImagPlot()
std::vector<double> GetImagPlot( const std::string& aName, int aMaxLen = -1 ) override;
std::vector<double> GetImagPlot( const std::string& aName, int aMaxLen = -1 ) override final;
///< @copydoc SPICE_SIMULATOR::GetMagPlot()
std::vector<double> GetMagPlot( const std::string& aName, int aMaxLen = -1 ) override;
std::vector<double> GetMagPlot( const std::string& aName, int aMaxLen = -1 ) override final;
///< @copydoc SPICE_SIMULATOR::GetPhasePlot()
std::vector<double> GetPhasePlot( const std::string& aName, int aMaxLen = -1 ) override;
std::vector<double> GetPhasePlot( const std::string& aName, int aMaxLen = -1 ) override final;
std::vector<std::string> GetSettingCommands() const override;
std::vector<std::string> GetSettingCommands() const override final;
///< @copydoc SPICE_SIMULATOR::GetNetlist()
virtual const std::string GetNetlist() const override;
virtual const std::string GetNetlist() const override final;
private:
void init();

View File

@ -24,13 +24,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "netlist_exporter_pspice_sim.h"
#include "ngspice_helpers.h"
#include <string_utils.h>
#include <macros.h> // for TO_UTF8 def
#include <wx/regex.h>
#include <wx/tokenzr.h>
wxString NETLIST_EXPORTER_PSPICE_SIM::ComponentToVector(
wxString NGSPICE_CIRCUIT_MODEL::ComponentToVector(
const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam ) const
{
wxString res;
@ -73,7 +73,7 @@ wxString NETLIST_EXPORTER_PSPICE_SIM::ComponentToVector(
}
SIM_PLOT_TYPE NETLIST_EXPORTER_PSPICE_SIM::VectorToSignal(
SIM_PLOT_TYPE NGSPICE_CIRCUIT_MODEL::VectorToSignal(
const std::string& aVector, wxString& aSignal ) const
{
using namespace std;
@ -108,7 +108,7 @@ SIM_PLOT_TYPE NETLIST_EXPORTER_PSPICE_SIM::VectorToSignal(
}
const std::vector<wxString>& NETLIST_EXPORTER_PSPICE_SIM::GetCurrents( SPICE_PRIMITIVE aPrimitive )
const std::vector<wxString>& NGSPICE_CIRCUIT_MODEL::GetCurrents( SPICE_PRIMITIVE aPrimitive )
{
static const std::vector<wxString> passive = { "I" };
static const std::vector<wxString> diode = { "Id" };
@ -139,7 +139,7 @@ const std::vector<wxString>& NETLIST_EXPORTER_PSPICE_SIM::GetCurrents( SPICE_PRI
}
wxString NETLIST_EXPORTER_PSPICE_SIM::GetSheetSimCommand()
wxString NGSPICE_CIRCUIT_MODEL::GetSheetSimCommand()
{
wxString simCmd;
@ -155,19 +155,19 @@ wxString NETLIST_EXPORTER_PSPICE_SIM::GetSheetSimCommand()
}
wxString NETLIST_EXPORTER_PSPICE_SIM::GetUsedSimCommand()
wxString NGSPICE_CIRCUIT_MODEL::GetUsedSimCommand()
{
return m_simCommand.IsEmpty() ? GetSheetSimCommand() : m_simCommand;
}
SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::GetSimType()
SIM_TYPE NGSPICE_CIRCUIT_MODEL::GetSimType()
{
return CommandToSimType( GetUsedSimCommand() );
}
SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( const wxString& aCmd )
SIM_TYPE NGSPICE_CIRCUIT_MODEL::CommandToSimType( const wxString& aCmd )
{
const std::vector<std::pair<wxString, SIM_TYPE>> simCmds = {
{ "^.ac\\M.*", ST_AC },
@ -193,7 +193,7 @@ SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( const wxString& aCmd )
}
bool NETLIST_EXPORTER_PSPICE_SIM::ParseDCCommand( const wxString& aCmd, SPICE_DC_PARAMS* aSource1,
bool NGSPICE_CIRCUIT_MODEL::ParseDCCommand( const wxString& aCmd, SPICE_DC_PARAMS* aSource1,
SPICE_DC_PARAMS* aSource2 )
{
if( !aCmd.Lower().StartsWith( ".dc" ) )
@ -225,7 +225,7 @@ bool NETLIST_EXPORTER_PSPICE_SIM::ParseDCCommand( const wxString& aCmd, SPICE_DC
}
void NETLIST_EXPORTER_PSPICE_SIM::writeDirectives( OUTPUTFORMATTER* aFormatter, unsigned aCtl ) const
void NGSPICE_CIRCUIT_MODEL::writeDirectives( OUTPUTFORMATTER* aFormatter, unsigned aCtl ) const
{
// Add a directive to obtain currents
//aFormatter->Print( 0, ".options savecurrents\n" ); // does not work :(
@ -233,7 +233,7 @@ void NETLIST_EXPORTER_PSPICE_SIM::writeDirectives( OUTPUTFORMATTER* aFormatter,
for( const auto& item : GetSpiceItems() )
{
for( const auto& current :
NETLIST_EXPORTER_PSPICE_SIM::GetCurrents( (SPICE_PRIMITIVE) item.m_primitive ) )
NGSPICE_CIRCUIT_MODEL::GetCurrents( (SPICE_PRIMITIVE) item.m_primitive ) )
{
if( !item.m_enabled )
continue;

View File

@ -31,6 +31,7 @@
#include <vector>
#include "sim_types.h"
#include "spice_simulator.h"
#include "spice_value.h"
@ -43,14 +44,14 @@ struct SPICE_DC_PARAMS
};
/// Special netlist exporter flavor that allows one to override simulation commands
class NETLIST_EXPORTER_PSPICE_SIM : public NETLIST_EXPORTER_PSPICE
class NGSPICE_CIRCUIT_MODEL : public NETLIST_EXPORTER_PSPICE, public SIMULATION_MODEL
{
public:
NETLIST_EXPORTER_PSPICE_SIM( SCHEMATIC_IFACE* aSchematic ) :
NGSPICE_CIRCUIT_MODEL( SCHEMATIC_IFACE* aSchematic ) :
NETLIST_EXPORTER_PSPICE( aSchematic )
{
}
virtual ~NETLIST_EXPORTER_PSPICE_SIM() {}
virtual ~NGSPICE_CIRCUIT_MODEL() {}
/**
* Return name of Spice dataset for a specific plot.
@ -80,6 +81,16 @@ public:
*/
static const std::vector<wxString>& GetCurrents( SPICE_PRIMITIVE aPrimitive );
void SetOptions( int aOptions )
{
m_options = aOptions;
}
bool GetNetlist( OUTPUTFORMATTER* aFormatter )
{
return NGSPICE_CIRCUIT_MODEL::Format( aFormatter, m_options );
}
/**
* Override the simulation command directive.
*/
@ -152,6 +163,7 @@ private:
///< Custom simulation command (has priority over the schematic sheet simulation commands)
wxString m_simCommand;
int m_options;
};
#endif /* NETLIST_EXPORTER_PSPICE_SIM_H */

View File

@ -27,7 +27,7 @@
#include "sim_panel_base.h"
#include "sim_plot_frame.h"
#include "netlist_exporter_pspice_sim.h"
#include "ngspice_helpers.h"
SIM_PANEL_BASE::SIM_PANEL_BASE() : m_simCommand( wxEmptyString )
@ -71,7 +71,7 @@ bool SIM_PANEL_BASE::IsPlottable( SIM_TYPE aSimType )
SIM_TYPE SIM_PANEL_BASE::GetType() const
{
return NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( m_simCommand );
return NGSPICE_CIRCUIT_MODEL::CommandToSimType( m_simCommand );
}

View File

@ -27,7 +27,7 @@
#define __SIM_PLOT_PANEL_BASE_H
#include "sim_types.h"
#include "netlist_exporter_pspice_sim.h"
#include "ngspice_helpers.h"
#include <wx/panel.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
@ -58,7 +58,7 @@ protected:
void setSimCommand( const wxString& aSimCommand )
{
wxCHECK_RET( GetType() == NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( aSimCommand ),
wxCHECK_RET( GetType() == NGSPICE_CIRCUIT_MODEL::CommandToSimType( aSimCommand ),
"Cannot change the type of simulation of the existing plot panel" );
m_simCommand = aSimCommand;

View File

@ -37,7 +37,7 @@
#include <widgets/tuner_slider.h>
#include <dialogs/dialog_signal_list.h>
#include "string_utils.h"
#include "netlist_exporter_pspice_sim.h"
#include "ngspice_helpers.h"
#include <pgm_base.h>
#include "ngspice.h"
#include "sim_plot_colors.h"
@ -129,7 +129,7 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
icon.CopyFromBitmap( KiBitmap( BITMAPS::simulator ) );
SetIcon( icon );
m_simulator = SPICE_SIMULATOR::CreateInstance( "ngspice" );
m_simulator = SIMULATOR::CreateInstance( "ngspice" );
if( !m_simulator )
{
@ -157,7 +157,7 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
// instead of being behind the dialog frame (as it does)
m_settingsDlg = nullptr;
m_exporter.reset( new NETLIST_EXPORTER_PSPICE_SIM( &m_schematicFrame->Schematic() ) );
m_exporter.reset( new NGSPICE_CIRCUIT_MODEL( &m_schematicFrame->Schematic() ) );
Bind( EVT_SIM_UPDATE, &SIM_PLOT_FRAME::onSimUpdate, this );
Bind( EVT_SIM_REPORT, &SIM_PLOT_FRAME::onSimReport, this );
@ -239,6 +239,7 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
SIM_PLOT_FRAME::~SIM_PLOT_FRAME()
{
m_simulator->Attach( nullptr );
m_simulator->SetReporter( nullptr );
delete m_reporter;
delete m_signalsIconColorList;
@ -456,8 +457,6 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
wxCHECK_RET( m_exporter->CommandToSimType( getCurrentSimCommand() ) != ST_UNKNOWN,
"Unknown simulation type" );
STRING_FORMATTER formatter;
if( !m_settingsDlg )
m_settingsDlg = new DIALOG_SIM_SETTINGS( this, m_exporter, m_simulator->Settings() );
@ -468,8 +467,9 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
else
m_exporter->SetSimCommand( aSimCommand );
m_exporter->SetOptions( m_settingsDlg->GetNetlistOptions() );
if( !m_exporter->Format( &formatter, m_settingsDlg->GetNetlistOptions() ) )
if( !m_simulator->Attach( m_exporter ) )
{
DisplayErrorMessage( this, _( "There were errors during netlist export, aborted." ) );
return;
@ -479,7 +479,6 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
if( simulatorLock.owns_lock() )
{
m_simulator->LoadNetlist( formatter.GetString() );
updateTuners();
applyTuners();
m_simulator->Run();
@ -492,7 +491,7 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( wxString aSimCommand )
{
SIM_PANEL_BASE* plotPanel = nullptr;
SIM_TYPE simType = NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( aSimCommand );
SIM_TYPE simType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( aSimCommand );
if( SIM_PANEL_BASE::IsPlottable( simType ) )
{
@ -614,7 +613,7 @@ SIM_PLOT_PANEL* SIM_PLOT_FRAME::GetCurrentPlot() const
}
const NETLIST_EXPORTER_PSPICE_SIM* SIM_PLOT_FRAME::GetExporter() const
const NGSPICE_CIRCUIT_MODEL* SIM_PLOT_FRAME::GetExporter() const
{
return m_exporter.get();
}
@ -1473,7 +1472,7 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
oldCommand = wxString();
wxString newCommand = m_settingsDlg->GetSimCommand();
SIM_TYPE newSimType = NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( newCommand );
SIM_TYPE newSimType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( newCommand );
// If it is a new simulation type, open a new plot
// For the DC sim, check if sweep source type has changed (char 4 will contain 'v',

View File

@ -51,7 +51,7 @@ class SCH_SYMBOL;
class SPICE_SIMULATOR;
class SPICE_SIMULATOR_SETTINGS;
class NETLIST_EXPORTER_PSPICE_SIM;
class NGSPICE_CIRCUIT_MODEL;
#include "sim_plot_panel.h"
#include "sim_panel_base.h"
@ -126,7 +126,7 @@ public:
/**
* Return the netlist exporter object used for simulations.
*/
const NETLIST_EXPORTER_PSPICE_SIM* GetExporter() const;
const NGSPICE_CIRCUIT_MODEL* GetExporter() const;
/**
* @return the current background option for plotting.
@ -333,7 +333,7 @@ private:
wxToolBarToolBase* m_toolSettings;
SCH_EDIT_FRAME* m_schematicFrame;
std::shared_ptr<NETLIST_EXPORTER_PSPICE_SIM> m_exporter;
std::shared_ptr<NGSPICE_CIRCUIT_MODEL> m_exporter;
std::shared_ptr<SPICE_SIMULATOR> m_simulator;
SIM_THREAD_REPORTER* m_reporter;

110
eeschema/sim/simulator.h Normal file
View File

@ -0,0 +1,110 @@
/*
* 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 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
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <mutex>
#include <memory>
class SPICE_SIMULATOR;
class SIMULATION_MODEL
{
public:
virtual ~SIMULATION_MODEL() {};
};
class SIMULATION_RESULTS
{
public:
virtual ~SIMULATION_RESULTS() {};
};
class SIMULATION
{
virtual ~SIMULATION(){};
};
class SIMULATOR
{
public:
SIMULATOR() :
m_simModel( nullptr )
{}
virtual ~SIMULATOR() {}
///< Create a simulator instance of particular type (currently only ngspice is handled)
static std::shared_ptr<SPICE_SIMULATOR> CreateInstance( const std::string& aName );
/*
* @return mutex for exclusive access to the simulator.
*/
std::mutex& GetMutex()
{
return m_mutex;
}
/**
* Point out the model that will be used in future simulations.
*
* @return True in case of success, false otherwise.
*/
virtual bool Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel )
{
m_simModel = aModel;
return true;
}
/**
* Execute the simulation with currently loaded netlist.
*
* @return True in case of success, false otherwise.
*/
virtual bool Run() = 0;
// virtual bool Run( SIMULATION* aSim ) = 0;
// virtual SIM_RESULT Run( SPICE_SIMULATION* aSim ) = 0;
/**
* Halt the simulation.
*
* @return True in case of success, false otherwise.
*/
virtual bool Stop() = 0;
/**
* Check if simulation is running at the moment.
*
* @return True if simulation is currently executed.
*/
virtual bool IsRunning() = 0;
protected:
///< Model that should be simulated.
std::shared_ptr<SIMULATION_MODEL> m_simModel;
private:
///< For interprocess synchronisation.
std::mutex m_mutex;
};

View File

@ -27,7 +27,7 @@
#include <confirm.h>
std::shared_ptr<SPICE_SIMULATOR> SPICE_SIMULATOR::CreateInstance( const std::string& )
std::shared_ptr<SPICE_SIMULATOR> SIMULATOR::CreateInstance( const std::string& )
{
try
{

View File

@ -29,6 +29,7 @@
#include "sim_types.h"
#include "spice_settings.h"
#include "simulator.h"
#include <mutex>
#include <string>
@ -43,19 +44,17 @@ class SPICE_REPORTER;
typedef std::complex<double> COMPLEX;
class SPICE_SIMULATOR
class SPICE_SIMULATOR : public SIMULATOR
{
public:
SPICE_SIMULATOR() :
SIMULATOR(),
m_reporter( nullptr ),
m_settings( nullptr )
{}
virtual ~SPICE_SIMULATOR() {}
///< Create a simulator instance of particular type (currently only ngspice is handled)
static std::shared_ptr<SPICE_SIMULATOR> CreateInstance( const std::string& aName );
/*
* Initialize the simulator using the optional \a aSettings.
*
@ -64,14 +63,6 @@ public:
*/
virtual void Init( const SPICE_SIMULATOR_SETTINGS* aSettings = nullptr ) = 0;
/*
* @return mutex for exclusive access to the simulator.
*/
std::mutex& GetMutex()
{
return m_mutex;
}
/**
* Load a netlist for the simulation.
*
@ -79,27 +70,6 @@ public:
*/
virtual bool LoadNetlist( const std::string& aNetlist ) = 0;
/**
* Execute the simulation with currently loaded netlist.
*
* @return True in case of success, false otherwise.
*/
virtual bool Run() = 0;
/**
* Halt the simulation.
*
* @return True in case of success, false otherwise.
*/
virtual bool Stop() = 0;
/**
* Check if simulation is running at the moment.
*
* @return True if simulation is currently executed.
*/
virtual bool IsRunning() = 0;
/**
* Execute a Spice command as if it was typed into console.
*
@ -213,10 +183,6 @@ protected:
///< We don't own this. We are just borrowing it from the #SCHEMATIC_SETTINGS.
std::shared_ptr<SPICE_SIMULATOR_SETTINGS> m_settings;
private:
///< For interprocess synchronisation.
std::mutex m_mutex;
};
#endif /* SPICE_SIMULATOR_H */

View File

@ -29,7 +29,7 @@
#include <sim/sim_plot_frame.h>
#include <sch_symbol.h>
#include <template_fieldnames.h>
#include <sim/netlist_exporter_pspice_sim.h>
#include <sim/ngspice_helpers.h>
#include <cmath> // log log1p expm1
#include <complex> // norm

View File

@ -71,7 +71,7 @@ if( KICAD_SPICE )
set( QA_EESCHEMA_SRCS
${QA_EESCHEMA_SRCS}
# Simulation tests
sim/test_netlist_exporter_pspice_sim.cpp
sim/test_ngspice_helpers.cpp
)
endif()

View File

@ -24,7 +24,7 @@
/**
* @file
* Test suite for NETLIST_EXPORTER_PSPICE_SIM
* Test suite for NGSPICE_CIRCUIT_MODEL
*/
#include <string.h>
@ -36,12 +36,12 @@
#include <project.h>
#include <schematic.h>
#include <settings/settings_manager.h>
#include <sim/netlist_exporter_pspice_sim.h>
#include <sim/ngspice_helpers.h>
class TEST_NETLIST_EXPORTER_PSPICE_SIM
class TEST_NGSPICE_HELPERS
{
public:
TEST_NETLIST_EXPORTER_PSPICE_SIM() :
TEST_NGSPICE_HELPERS() :
m_manager( true ),
m_schematic( nullptr ),
m_exporter( &m_schematic )
@ -50,7 +50,7 @@ public:
m_schematic.SetProject( &m_manager.Prj() );
}
virtual ~TEST_NETLIST_EXPORTER_PSPICE_SIM()
virtual ~TEST_NGSPICE_HELPERS()
{
m_schematic.Reset();
}
@ -59,14 +59,14 @@ public:
SCHEMATIC m_schematic;
NETLIST_EXPORTER_PSPICE_SIM m_exporter;
NGSPICE_CIRCUIT_MODEL m_exporter;
};
/**
* Declare the test suite
*/
BOOST_FIXTURE_TEST_SUITE( NetlistExporterPspiceSim, TEST_NETLIST_EXPORTER_PSPICE_SIM )
BOOST_FIXTURE_TEST_SUITE( NgspiceCircuitModel, TEST_NGSPICE_HELPERS )
/**
@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE( CommandToSimType )
for( auto& step : testData )
{
SIM_TYPE result = NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( step.command );
SIM_TYPE result = NGSPICE_CIRCUIT_MODEL::CommandToSimType( step.command );
BOOST_CHECK_EQUAL( result, step.type );
}
@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE( CommandToSimType )
for( auto& step : testData )
{
step.command.Append( "\n" );
SIM_TYPE result = NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( step.command );
SIM_TYPE result = NGSPICE_CIRCUIT_MODEL::CommandToSimType( step.command );
BOOST_CHECK_EQUAL( result, step.type );
}