Simulator code formatting and clean up
This commit is contained in:
parent
957c6ec417
commit
eeeb3e0a9a
|
@ -44,8 +44,6 @@ wxString NETLIST_EXPORTER_PSPICE_SIM::GetSpiceVector( const wxString& aName, SIM
|
|||
return wxString::Format( "V(%d)", it->second );
|
||||
}
|
||||
|
||||
|
||||
/// @todo check is Lower() is required
|
||||
else if( aType & SPT_CURRENT )
|
||||
{
|
||||
return wxString::Format( "@%s[%s]", GetSpiceDevice( aName ).Lower(),
|
||||
|
@ -183,5 +181,4 @@ void NETLIST_EXPORTER_PSPICE_SIM::writeDirectives( OUTPUTFORMATTER* aFormatter,
|
|||
// Finish with our custom simulation command
|
||||
aFormatter->Print( 0, "%s\n", (const char*) m_simCommand.c_str() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -64,30 +64,53 @@ public:
|
|||
*/
|
||||
static const std::vector<wxString>& GetCurrents( SPICE_PRIMITIVE aPrimitive );
|
||||
|
||||
/**
|
||||
* @brief Overrides the simulation command directive.
|
||||
*/
|
||||
void SetSimCommand( const wxString& aCmd )
|
||||
{
|
||||
m_simCommand = aCmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the simulation command directive.
|
||||
*/
|
||||
const wxString& GetSimCommand() const
|
||||
{
|
||||
return m_simCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the simulation command directive.
|
||||
*/
|
||||
void ClearSimCommand()
|
||||
{
|
||||
m_simCommand.Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns simulation type basing on the simulation command directives.
|
||||
* Simulation directives set using SetSimCommand() have priority over the ones placed in
|
||||
* schematic sheets.
|
||||
*/
|
||||
SIM_TYPE GetSimType();
|
||||
|
||||
/**
|
||||
* @brief Returns simulation command directives placed in schematic sheets (if any).
|
||||
*/
|
||||
wxString GetSheetSimCommand();
|
||||
|
||||
/**
|
||||
* @brief Determines if a directive is a simulation command.
|
||||
*/
|
||||
static bool IsSimCommand( const wxString& aCmd )
|
||||
{
|
||||
return CommandToSimType( aCmd ) != ST_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns simulation type basing on a simulation command directive.
|
||||
*/
|
||||
static SIM_TYPE CommandToSimType( const wxString& aCmd );
|
||||
|
||||
protected:
|
||||
|
@ -95,7 +118,7 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
///> Overridden simulation command
|
||||
///> Custom simulation command (has priority over the schematic sheet simulation commands)
|
||||
wxString m_simCommand;
|
||||
};
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ NGSPICE::NGSPICE()
|
|||
m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll->GetSymbol( "ngSpice_AllPlots" );
|
||||
m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll->GetSymbol( "ngSpice_AllVecs" );
|
||||
m_ngSpice_Running = (ngSpice_Running) m_dll->GetSymbol( "ngSpice_running" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -243,7 +242,7 @@ bool NGSPICE::LoadNetlist( const string& aNetlist )
|
|||
bool NGSPICE::Run()
|
||||
{
|
||||
setlocale( LC_ALL, "C" );
|
||||
bool rv = Command( "bg_run" );
|
||||
bool rv = Command( "bg_run" ); // bg_* commands execute in a separate thread
|
||||
setlocale( LC_ALL, "" );
|
||||
return rv;
|
||||
}
|
||||
|
@ -252,7 +251,7 @@ bool NGSPICE::Run()
|
|||
bool NGSPICE::Stop()
|
||||
{
|
||||
setlocale( LC_ALL, "C" );
|
||||
bool rv = Command( "bg_halt" );
|
||||
bool rv = Command( "bg_halt" ); // bg_* commands execute in a separate thread
|
||||
setlocale( LC_ALL, "" );
|
||||
return rv;
|
||||
}
|
||||
|
@ -301,10 +300,11 @@ string NGSPICE::GetXAxis( SIM_TYPE aType ) const
|
|||
return string( "" );
|
||||
}
|
||||
|
||||
int NGSPICE::cbControlledExit ( int status, bool immediate, bool exit_upon_quit, int id, void *user )
|
||||
|
||||
int NGSPICE::cbControlledExit( int status, bool immediate, bool exit_upon_quit, int id, void* user )
|
||||
{
|
||||
printf("stat %d immed %d quit %d\n", status, !!immediate, !!exit_upon_quit);
|
||||
return 0;
|
||||
//printf("stat %d immed %d quit %d\n", status, !!immediate, !!exit_upon_quit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,32 +36,54 @@ public:
|
|||
NGSPICE();
|
||||
virtual ~NGSPICE();
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::Init()
|
||||
void Init() override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::LoadNetlist()
|
||||
bool LoadNetlist( const std::string& aNetlist ) override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::Run()
|
||||
bool Run() override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::Stop()
|
||||
bool Stop() override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::IsRunning()
|
||||
bool IsRunning() override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::Command()
|
||||
bool Command( const std::string& aCmd ) override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::GetXAxis()
|
||||
std::string GetXAxis( SIM_TYPE aType ) const override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::GetPlot()
|
||||
std::vector<COMPLEX> GetPlot( const std::string& aName, int aMaxLen = -1 ) override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::GetRealPlot()
|
||||
std::vector<double> GetRealPlot( const std::string& aName, int aMaxLen = -1 ) override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::GetImagPlot()
|
||||
std::vector<double> GetImagPlot( const std::string& aName, int aMaxLen = -1 ) override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::GetMagPlot()
|
||||
std::vector<double> GetMagPlot( const std::string& aName, int aMaxLen = -1 ) override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::GetPhasePlot()
|
||||
std::vector<double> GetPhasePlot( const std::string& aName, int aMaxLen = -1 ) override;
|
||||
|
||||
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 pvector_info (*ngGet_Vec_Info)( char* vecname );
|
||||
typedef char** (*ngSpice_AllPlots)( void );
|
||||
typedef char** (*ngSpice_AllVecs)( char* plotname );
|
||||
typedef bool (*ngSpice_Running)( void );
|
||||
|
||||
// ngspice library functions
|
||||
typedef int (*ngSpice_Circ)(char** circarray);
|
||||
typedef int (*ngSpice_Command)(char* command);
|
||||
typedef pvector_info (*ngGet_Vec_Info)(char* vecname);
|
||||
typedef char** (*ngSpice_AllPlots)(void);
|
||||
typedef char** (*ngSpice_AllVecs)(char* plotname);
|
||||
typedef bool (*ngSpice_Running)(void);
|
||||
|
||||
///> Handles to DLL functions
|
||||
ngSpice_Init m_ngSpice_Init;
|
||||
ngSpice_Circ m_ngSpice_Circ;
|
||||
ngSpice_Command m_ngSpice_Command;
|
||||
|
@ -72,10 +94,11 @@ private:
|
|||
|
||||
wxDynamicLibrary* m_dll;
|
||||
|
||||
// Callback functions
|
||||
static int cbSendChar( char* what, int id, void* user );
|
||||
static int cbSendStat( char* what, int id, void* user );
|
||||
static int cbBGThreadRunning( bool is_running, int id, void* user );
|
||||
static int cbControlledExit ( int status, bool immediate, bool exit_upon_quit, int id, void *user );
|
||||
static int cbControlledExit( int status, bool immediate, bool exit_upon_quit, int id, void* user );
|
||||
|
||||
void dump();
|
||||
};
|
||||
|
|
|
@ -45,6 +45,7 @@ SIM_PLOT_TYPE operator|( SIM_PLOT_TYPE aFirst, SIM_PLOT_TYPE aSecond )
|
|||
return (SIM_PLOT_TYPE) res;
|
||||
}
|
||||
|
||||
|
||||
class SIM_THREAD_REPORTER : public SPICE_REPORTER
|
||||
{
|
||||
public:
|
||||
|
@ -117,11 +118,17 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
|
|||
Connect( EVT_SIM_FINISHED, wxCommandEventHandler( SIM_PLOT_FRAME::onSimFinished ), NULL, this );
|
||||
Connect( EVT_SIM_CURSOR_UPDATE, wxCommandEventHandler( SIM_PLOT_FRAME::onCursorUpdate ), NULL, this );
|
||||
|
||||
m_toolSimulate = m_toolBar->AddTool( ID_SIM_RUN, _("Run/Stop Simulation"), KiBitmap( sim_run_xpm ), _("Run Simulation"), wxITEM_NORMAL );
|
||||
m_toolAddSignals = m_toolBar->AddTool( ID_SIM_ADD_SIGNALS, _("Add Signals"), KiBitmap( sim_add_signal_xpm ), _("Add signals to plot"), wxITEM_NORMAL );
|
||||
m_toolProbe = m_toolBar->AddTool( ID_SIM_PROBE, _("Probe"), KiBitmap( sim_probe_xpm ),_("Probe signals on the schematic"), wxITEM_NORMAL );
|
||||
m_toolTune = m_toolBar->AddTool( ID_SIM_TUNE, _("Tune"), KiBitmap( sim_tune_xpm ), _("Tune component values"), wxITEM_NORMAL );
|
||||
m_toolSettings = m_toolBar->AddTool( wxID_ANY, _("Settings"), KiBitmap( sim_settings_xpm ), _("Simulation settings"), wxITEM_NORMAL );
|
||||
// Toolbar buttons
|
||||
m_toolSimulate = m_toolBar->AddTool( ID_SIM_RUN, _( "Run/Stop Simulation" ),
|
||||
KiBitmap( sim_run_xpm ), _( "Run Simulation" ), wxITEM_NORMAL );
|
||||
m_toolAddSignals = m_toolBar->AddTool( ID_SIM_ADD_SIGNALS, _( "Add Signals" ),
|
||||
KiBitmap( sim_add_signal_xpm ), _( "Add signals to plot" ), wxITEM_NORMAL );
|
||||
m_toolProbe = m_toolBar->AddTool( ID_SIM_PROBE, _( "Probe" ),
|
||||
KiBitmap( sim_probe_xpm ), _( "Probe signals on the schematic" ), wxITEM_NORMAL );
|
||||
m_toolTune = m_toolBar->AddTool( ID_SIM_TUNE, _( "Tune" ),
|
||||
KiBitmap( sim_tune_xpm ), _( "Tune component values" ), wxITEM_NORMAL );
|
||||
m_toolSettings = m_toolBar->AddTool( wxID_ANY, _( "Settings" ),
|
||||
KiBitmap( sim_settings_xpm ), _( "Simulation settings" ), wxITEM_NORMAL );
|
||||
|
||||
Connect( m_toolSimulate->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME::onSimulate ), NULL, this );
|
||||
Connect( m_toolAddSignals->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME::onAddSignal ), NULL, this );
|
||||
|
@ -129,6 +136,7 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
|
|||
Connect( m_toolTune->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME::onTune ), NULL, this );
|
||||
Connect( m_toolSettings->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME::onSettings ), NULL, this );
|
||||
|
||||
// Bind toolbar buttons event to existing menu event handlers, so they behave the same
|
||||
Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onSimulate, this, m_runSimulation->GetId() );
|
||||
Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onAddSignal, this, m_addSignals->GetId() );
|
||||
Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onProbe, this, m_probeSignals->GetId() );
|
||||
|
@ -136,7 +144,7 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
|
|||
Bind( wxEVT_COMMAND_MENU_SELECTED, &SIM_PLOT_FRAME::onSettings, this, m_settings->GetId() );
|
||||
|
||||
m_toolBar->Realize();
|
||||
m_plotNotebook->SetPageText(0, _("Welcome!") );
|
||||
m_plotNotebook->SetPageText( 0, _( "Welcome!" ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -180,8 +188,6 @@ void SIM_PLOT_FRAME::StartSimulation()
|
|||
updateTuners();
|
||||
applyTuners();
|
||||
m_simulator->Run();
|
||||
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
||||
|
@ -746,21 +752,6 @@ void SIM_PLOT_FRAME::menuShowLegendUpdate( wxUpdateUIEvent& event )
|
|||
event.Check( plot ? plot->IsLegendShown() : false );
|
||||
}
|
||||
|
||||
#if 0
|
||||
void SIM_PLOT_FRAME::menuShowCoords( wxCommandEvent& event )
|
||||
{
|
||||
SIM_PLOT_PANEL* plot = CurrentPlot();
|
||||
plot->ShowCoords( !plot->IsCoordsShown() );
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::menuShowCoordsUpdate( wxUpdateUIEvent& event )
|
||||
{
|
||||
SIM_PLOT_PANEL* plot = CurrentPlot();
|
||||
event.Check( plot ? plot->IsCoordsShown() : false );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::onPlotClose( wxAuiNotebookEvent& event )
|
||||
{
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
#define __sim_plot_frame__
|
||||
|
||||
/**
|
||||
@file Subclass of SIM_PLOT_FRAME_BASE, which is generated by wxFormBuilder. */
|
||||
* @file Subclass of SIM_PLOT_FRAME_BASE, which is generated by wxFormBuilder.
|
||||
*/
|
||||
|
||||
#include "sim_plot_frame_base.h"
|
||||
#include "sim_types.h"
|
||||
|
@ -49,7 +50,7 @@ class NETLIST_EXPORTER_PSPICE_SIM;
|
|||
class SIM_PLOT_PANEL;
|
||||
class TUNER_SLIDER;
|
||||
|
||||
/// @todo description
|
||||
///> Trace descriptor class
|
||||
class TRACE_DESC
|
||||
{
|
||||
public:
|
||||
|
@ -102,191 +103,218 @@ private:
|
|||
/** Implementing SIM_PLOT_FRAME_BASE */
|
||||
class SIM_PLOT_FRAME : public SIM_PLOT_FRAME_BASE
|
||||
{
|
||||
public:
|
||||
/** Constructor */
|
||||
SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||
~SIM_PLOT_FRAME();
|
||||
public:
|
||||
/** Constructor */
|
||||
SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||
~SIM_PLOT_FRAME();
|
||||
|
||||
void StartSimulation();
|
||||
void StopSimulation();
|
||||
bool IsSimulationRunning();
|
||||
void StartSimulation();
|
||||
void StopSimulation();
|
||||
bool IsSimulationRunning();
|
||||
|
||||
/**
|
||||
* @brief Creates a new plot panel for a given simulation type and adds it to the main
|
||||
* notebook.
|
||||
* @param aSimType is requested simulation type.
|
||||
* @return The new plot panel.
|
||||
*/
|
||||
SIM_PLOT_PANEL* NewPlotPanel( SIM_TYPE aSimType );
|
||||
/**
|
||||
* @brief Creates a new plot panel for a given simulation type and adds it to the main
|
||||
* notebook.
|
||||
* @param aSimType is requested simulation type.
|
||||
* @return The new plot panel.
|
||||
*/
|
||||
SIM_PLOT_PANEL* NewPlotPanel( SIM_TYPE aSimType );
|
||||
|
||||
void AddVoltagePlot( const wxString& aNetName );
|
||||
void AddCurrentPlot( const wxString& aDeviceName, const wxString& aParam );
|
||||
/**
|
||||
* @brief Adds a voltage plot for a given net name.
|
||||
* @param aNetName is the net name for which a voltage plot should be created.
|
||||
*/
|
||||
void AddVoltagePlot( const wxString& aNetName );
|
||||
|
||||
void AddTuner( SCH_COMPONENT* aComponent );
|
||||
void RemoveTuner( TUNER_SLIDER* aTuner, bool aErase = true );
|
||||
/**
|
||||
* @brief Adds a current plot for a particular device.
|
||||
* @param aDeviceName is the device name (e.g. R1, C1).
|
||||
* @param aParam is the current type (e.g. I, Ic, Id).
|
||||
*/
|
||||
void AddCurrentPlot( const wxString& aDeviceName, const wxString& aParam );
|
||||
|
||||
SIM_PLOT_PANEL* CurrentPlot() const;
|
||||
/**
|
||||
* @brief Adds a tuner for a component.
|
||||
*/
|
||||
void AddTuner( SCH_COMPONENT* aComponent );
|
||||
|
||||
private:
|
||||
void relayout();
|
||||
/**
|
||||
* @brief Adds a new plot to the current panel.
|
||||
* @param aName is the device/net name.
|
||||
* @param aType describes the type of plot.
|
||||
* @param aParam is the parameter for the device/net (e.g. I, Id, V).
|
||||
*/
|
||||
void addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam );
|
||||
/**
|
||||
* @brief Removes an existing tuner.
|
||||
* @param aTuner is the tuner to be removed.
|
||||
* @param aErase decides whether the tuner should be also removed from the tuners list.
|
||||
* Otherwise it is removed only from the SIM_PLOT_FRAME pane.
|
||||
*/
|
||||
void RemoveTuner( TUNER_SLIDER* aTuner, bool aErase = true );
|
||||
|
||||
/**
|
||||
* @brief Removes a plot with a specific title.
|
||||
* @param aPlotName is the full plot title (e.g. I(Net-C1-Pad1)).
|
||||
* @param aErase decides if plot should be removed from corresponding TRACE_MAP (see m_plots).
|
||||
*/
|
||||
void removePlot( const wxString& aPlotName, bool aErase = true );
|
||||
/**
|
||||
* @brief Returns the currently opened plot panel (or NULL if there is none).
|
||||
*/
|
||||
SIM_PLOT_PANEL* CurrentPlot() const;
|
||||
|
||||
void updateNetlistExporter();
|
||||
private:
|
||||
/**
|
||||
* @brief Adds a new plot to the current panel.
|
||||
* @param aName is the device/net name.
|
||||
* @param aType describes the type of plot.
|
||||
* @param aParam is the parameter for the device/net (e.g. I, Id, V).
|
||||
*/
|
||||
void addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam );
|
||||
|
||||
/**
|
||||
* @brief Updates plot in a particular SIM_PLOT_PANEL. If the panel does not contain
|
||||
* the plot, it will be added.
|
||||
* @param aDescriptor contains the plot description.
|
||||
* @param aPanel is the panel that should receive the update.
|
||||
* @return True if a plot was successfully added/updated.
|
||||
*/
|
||||
bool updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL* aPanel );
|
||||
/**
|
||||
* @brief Removes a plot with a specific title.
|
||||
* @param aPlotName is the full plot title (e.g. I(Net-C1-Pad1)).
|
||||
* @param aErase decides if plot should be removed from corresponding TRACE_MAP (see m_plots).
|
||||
*/
|
||||
void removePlot( const wxString& aPlotName, bool aErase = true );
|
||||
|
||||
/**
|
||||
* @brief Updates the list of currently plotted signals.
|
||||
*/
|
||||
void updateSignalList();
|
||||
/**
|
||||
* @brief Reloads the current schematic for the netlist exporter.
|
||||
*/
|
||||
void updateNetlistExporter();
|
||||
|
||||
/**
|
||||
* @brief Updates the cursor values list.
|
||||
*/
|
||||
void updateCursors();
|
||||
/**
|
||||
* @brief Updates plot in a particular SIM_PLOT_PANEL. If the panel does not contain
|
||||
* the plot, it will be added.
|
||||
* @param aDescriptor contains the plot description.
|
||||
* @param aPanel is the panel that should receive the update.
|
||||
* @return True if a plot was successfully added/updated.
|
||||
*/
|
||||
bool updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL* aPanel );
|
||||
|
||||
/**
|
||||
* @brief Filters out tuners for components that do not exist anymore.
|
||||
* Decisions are based on the current NETLIST_EXPORTER data.
|
||||
*/
|
||||
void updateTuners();
|
||||
/**
|
||||
* @brief Updates the list of currently plotted signals.
|
||||
*/
|
||||
void updateSignalList();
|
||||
|
||||
/**
|
||||
* @brief Applies component values specified using tunder sliders to the current netlist.
|
||||
*/
|
||||
void applyTuners();
|
||||
/**
|
||||
* @brief Updates the cursor values list.
|
||||
*/
|
||||
void updateCursors();
|
||||
|
||||
/**
|
||||
* @brief Loads plot settings from a file.
|
||||
* @param aPath is the file name.
|
||||
* @return True if successful.
|
||||
*/
|
||||
bool loadWorkbook( const wxString& aPath );
|
||||
/**
|
||||
* @brief Filters out tuners for components that do not exist anymore.
|
||||
* Decisions are based on the current NETLIST_EXPORTER data.
|
||||
*/
|
||||
void updateTuners();
|
||||
|
||||
/**
|
||||
* @brief Saves plot settings to a file.
|
||||
* @param aPath is the file name.
|
||||
* @return True if successful.
|
||||
*/
|
||||
bool saveWorkbook( const wxString& aPath );
|
||||
/**
|
||||
* @brief Applies component values specified using tunder sliders to the current netlist.
|
||||
*/
|
||||
void applyTuners();
|
||||
|
||||
SIM_PLOT_TYPE GetXAxisType( SIM_TYPE aType ) const;
|
||||
/**
|
||||
* @brief Loads plot settings from a file.
|
||||
* @param aPath is the file name.
|
||||
* @return True if successful.
|
||||
*/
|
||||
bool loadWorkbook( const wxString& aPath );
|
||||
|
||||
// Menu handlers
|
||||
void menuNewPlot( wxCommandEvent& aEvent ) override;
|
||||
void menuOpenWorkbook( wxCommandEvent& event ) override;
|
||||
void menuSaveWorkbook( wxCommandEvent& event ) override;
|
||||
/**
|
||||
* @brief Saves plot settings to a file.
|
||||
* @param aPath is the file name.
|
||||
* @return True if successful.
|
||||
*/
|
||||
bool saveWorkbook( const wxString& aPath );
|
||||
|
||||
void menuExit( wxCommandEvent& event ) override
|
||||
{
|
||||
Close();
|
||||
}
|
||||
/**
|
||||
* @brief Returns X axis for a given simulation type.
|
||||
*/
|
||||
SIM_PLOT_TYPE GetXAxisType( SIM_TYPE aType ) const;
|
||||
|
||||
void menuSaveImage( wxCommandEvent& event ) override;
|
||||
void menuSaveCsv( wxCommandEvent& event ) override;
|
||||
void menuZoomIn( wxCommandEvent& event ) override;
|
||||
void menuZoomOut( wxCommandEvent& event ) override;
|
||||
void menuZoomFit( wxCommandEvent& event ) override;
|
||||
void menuShowGrid( wxCommandEvent& event ) override;
|
||||
void menuShowGridUpdate( wxUpdateUIEvent& event ) override;
|
||||
void menuShowLegend( wxCommandEvent& event ) override;
|
||||
void menuShowLegendUpdate( wxUpdateUIEvent& event ) override;
|
||||
//void menuShowCoords( wxCommandEvent& event ) override;
|
||||
//void menuShowCoordsUpdate( wxUpdateUIEvent& event ) override;
|
||||
// Menu handlers
|
||||
void menuNewPlot( wxCommandEvent& aEvent ) override;
|
||||
void menuOpenWorkbook( wxCommandEvent& event ) override;
|
||||
void menuSaveWorkbook( wxCommandEvent& event ) override;
|
||||
|
||||
// Event handlers
|
||||
void onPlotChanged( wxAuiNotebookEvent& event ) override;
|
||||
void onPlotClose( wxAuiNotebookEvent& event ) override;
|
||||
void menuExit( wxCommandEvent& event ) override
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void onSignalDblClick( wxCommandEvent& event ) override;
|
||||
void onSignalRClick( wxMouseEvent& event ) override;
|
||||
void menuSaveImage( wxCommandEvent& event ) override;
|
||||
void menuSaveCsv( wxCommandEvent& event ) override;
|
||||
void menuZoomIn( wxCommandEvent& event ) override;
|
||||
void menuZoomOut( wxCommandEvent& event ) override;
|
||||
void menuZoomFit( wxCommandEvent& event ) override;
|
||||
void menuShowGrid( wxCommandEvent& event ) override;
|
||||
void menuShowGridUpdate( wxUpdateUIEvent& event ) override;
|
||||
void menuShowLegend( wxCommandEvent& event ) override;
|
||||
void menuShowLegendUpdate( wxUpdateUIEvent& event ) override;
|
||||
|
||||
void onSimulate( wxCommandEvent& event );
|
||||
void onSettings( wxCommandEvent& event );
|
||||
void onAddSignal( wxCommandEvent& event );
|
||||
void onProbe( wxCommandEvent& event );
|
||||
void onTune( wxCommandEvent& event );
|
||||
// Event handlers
|
||||
void onPlotChanged( wxAuiNotebookEvent& event ) override;
|
||||
void onPlotClose( wxAuiNotebookEvent& event ) override;
|
||||
|
||||
void onClose( wxCloseEvent& aEvent );
|
||||
void onSignalDblClick( wxCommandEvent& event ) override;
|
||||
void onSignalRClick( wxMouseEvent& event ) override;
|
||||
|
||||
void onCursorUpdate( wxCommandEvent& aEvent );
|
||||
void onSimUpdate( wxCommandEvent& aEvent );
|
||||
void onSimReport( wxCommandEvent& aEvent );
|
||||
void onSimStarted( wxCommandEvent& aEvent );
|
||||
void onSimFinished( wxCommandEvent& aEvent );
|
||||
void onSimulate( wxCommandEvent& event );
|
||||
void onSettings( wxCommandEvent& event );
|
||||
void onAddSignal( wxCommandEvent& event );
|
||||
void onProbe( wxCommandEvent& event );
|
||||
void onTune( wxCommandEvent& event );
|
||||
|
||||
wxToolBarToolBase* m_toolSimulate;
|
||||
wxToolBarToolBase* m_toolAddSignals;
|
||||
wxToolBarToolBase* m_toolProbe;
|
||||
wxToolBarToolBase* m_toolTune;
|
||||
wxToolBarToolBase* m_toolSettings;
|
||||
void onClose( wxCloseEvent& aEvent );
|
||||
|
||||
SCH_EDIT_FRAME* m_schematicFrame;
|
||||
std::unique_ptr<NETLIST_EXPORTER_PSPICE_SIM> m_exporter;
|
||||
std::unique_ptr<SPICE_SIMULATOR> m_simulator;
|
||||
void onCursorUpdate( wxCommandEvent& aEvent );
|
||||
void onSimUpdate( wxCommandEvent& aEvent );
|
||||
void onSimReport( wxCommandEvent& aEvent );
|
||||
void onSimStarted( wxCommandEvent& aEvent );
|
||||
void onSimFinished( wxCommandEvent& aEvent );
|
||||
|
||||
typedef std::map<wxString, TRACE_DESC> TRACE_MAP;
|
||||
// Toolbar buttons
|
||||
wxToolBarToolBase* m_toolSimulate;
|
||||
wxToolBarToolBase* m_toolAddSignals;
|
||||
wxToolBarToolBase* m_toolProbe;
|
||||
wxToolBarToolBase* m_toolTune;
|
||||
wxToolBarToolBase* m_toolSettings;
|
||||
|
||||
struct PLOT_INFO
|
||||
{
|
||||
///> Map of the traces displayed on the plot
|
||||
TRACE_MAP m_traces;
|
||||
SCH_EDIT_FRAME* m_schematicFrame;
|
||||
std::unique_ptr<NETLIST_EXPORTER_PSPICE_SIM> m_exporter;
|
||||
std::unique_ptr<SPICE_SIMULATOR> m_simulator;
|
||||
|
||||
///> Spice directive used to execute the simulation
|
||||
wxString m_simCommand;
|
||||
};
|
||||
typedef std::map<wxString, TRACE_DESC> TRACE_MAP;
|
||||
|
||||
///> Map of plot panels and associated data
|
||||
std::map<SIM_PLOT_PANEL*, PLOT_INFO> m_plots;
|
||||
struct PLOT_INFO
|
||||
{
|
||||
///> Map of the traces displayed on the plot
|
||||
TRACE_MAP m_traces;
|
||||
|
||||
///> List of currently displayed tuners
|
||||
std::list<TUNER_SLIDER*> m_tuners;
|
||||
///> Spice directive used to execute the simulation
|
||||
wxString m_simCommand;
|
||||
};
|
||||
|
||||
// Trick to preserve settings between runs
|
||||
DIALOG_SIM_SETTINGS m_settingsDlg;
|
||||
///> Map of plot panels and associated data
|
||||
std::map<SIM_PLOT_PANEL*, PLOT_INFO> m_plots;
|
||||
|
||||
// Right click context menu for signals in the listbox
|
||||
class SIGNAL_CONTEXT_MENU : public wxMenu
|
||||
{
|
||||
public:
|
||||
SIGNAL_CONTEXT_MENU( const wxString& aSignal, SIM_PLOT_FRAME* aPlotFrame );
|
||||
///> List of currently displayed tuners
|
||||
std::list<TUNER_SLIDER*> m_tuners;
|
||||
|
||||
private:
|
||||
void onMenuEvent( wxMenuEvent& aEvent );
|
||||
// Trick to preserve settings between runs
|
||||
DIALOG_SIM_SETTINGS m_settingsDlg;
|
||||
|
||||
const wxString& m_signal;
|
||||
SIM_PLOT_FRAME* m_plotFrame;
|
||||
// Right click context menu for signals in the listbox
|
||||
class SIGNAL_CONTEXT_MENU : public wxMenu
|
||||
{
|
||||
public:
|
||||
SIGNAL_CONTEXT_MENU( const wxString& aSignal, SIM_PLOT_FRAME* aPlotFrame );
|
||||
|
||||
enum SIGNAL_CONTEXT_MENU_EVENTS
|
||||
{
|
||||
HIDE_SIGNAL,
|
||||
SHOW_CURSOR,
|
||||
HIDE_CURSOR
|
||||
};
|
||||
};
|
||||
private:
|
||||
void onMenuEvent( wxMenuEvent& aEvent );
|
||||
|
||||
///> Panel that was used as the most recent one for simulations
|
||||
SIM_PLOT_PANEL* m_lastSimPlot;
|
||||
const wxString& m_signal;
|
||||
SIM_PLOT_FRAME* m_plotFrame;
|
||||
|
||||
enum SIGNAL_CONTEXT_MENU_EVENTS
|
||||
{
|
||||
HIDE_SIGNAL,
|
||||
SHOW_CURSOR,
|
||||
HIDE_CURSOR
|
||||
};
|
||||
};
|
||||
|
||||
///> Panel that was used as the most recent one for simulations
|
||||
SIM_PLOT_PANEL* m_lastSimPlot;
|
||||
};
|
||||
|
||||
// Commands
|
||||
|
|
|
@ -28,80 +28,88 @@
|
|||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
static wxString formatFloat (double x, int nDigits)
|
||||
static wxString formatFloat( double x, int nDigits )
|
||||
{
|
||||
wxString rv, fmt;
|
||||
|
||||
if(nDigits)
|
||||
if( nDigits )
|
||||
{
|
||||
fmt = wxT("%.0Nf");
|
||||
fmt = wxT( "%.0Nf" );
|
||||
fmt[3] = '0' + nDigits;
|
||||
} else {
|
||||
fmt = wxT("%.0f");
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt = wxT( "%.0f" );
|
||||
}
|
||||
|
||||
rv.Printf(fmt, x);
|
||||
rv.Printf( fmt, x );
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void getSISuffix ( double x, const wxString& unit, int& power, wxString& suffix )
|
||||
|
||||
static void getSISuffix( double x, const wxString& unit, int& power, wxString& suffix )
|
||||
{
|
||||
const int n_powers = 11;
|
||||
const struct {
|
||||
|
||||
const struct
|
||||
{
|
||||
double exponent;
|
||||
char suffix;
|
||||
} powers[] = {
|
||||
{-18,'a'},
|
||||
{-15,'f'},
|
||||
{-12,'p'},
|
||||
{-9,'n'},
|
||||
{-6,'u'},
|
||||
{-3,'m'},
|
||||
{0, 0},
|
||||
{3, 'k'},
|
||||
{6, 'M'},
|
||||
{9, 'G'},
|
||||
{12, 'T'},
|
||||
{15, 'P'}
|
||||
} powers[] =
|
||||
{
|
||||
{ -18, 'a' },
|
||||
{ -15, 'f' },
|
||||
{ -12, 'p' },
|
||||
{ -9, 'n' },
|
||||
{ -6, 'u' },
|
||||
{ -3, 'm' },
|
||||
{ 0, 0 },
|
||||
{ 3, 'k' },
|
||||
{ 6, 'M' },
|
||||
{ 9, 'G' },
|
||||
{ 12, 'T' },
|
||||
{ 14, 'P' }
|
||||
};
|
||||
|
||||
power = 0;
|
||||
suffix = unit;
|
||||
|
||||
if (x == 0.0)
|
||||
if( x == 0.0 )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i <n_powers - 1;i++)
|
||||
for( int i = 0; i < n_powers - 1; i++ )
|
||||
{
|
||||
double r_cur = pow(10, powers[i].exponent);
|
||||
double r_cur = pow( 10, powers[i].exponent );
|
||||
|
||||
if( fabs(x) >= r_cur && fabs(x) < r_cur * 1000.0 )
|
||||
if( fabs( x ) >= r_cur && fabs( x ) < r_cur * 1000.0 )
|
||||
{
|
||||
power = powers[i].exponent;
|
||||
if ( powers[i].suffix )
|
||||
suffix = wxString(powers[i].suffix) + unit;
|
||||
|
||||
if( powers[i].suffix )
|
||||
suffix = wxString( powers[i].suffix ) + unit;
|
||||
else
|
||||
suffix = unit;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int countDecimalDigits ( double x, int maxDigits )
|
||||
|
||||
static int countDecimalDigits( double x, int maxDigits )
|
||||
{
|
||||
int64_t k = (int) ( ( x - floor(x)) * pow ( 10.0, (double) maxDigits ));
|
||||
int64_t k = (int)( ( x - floor( x ) ) * pow( 10.0, (double) maxDigits ) );
|
||||
int n = 0;
|
||||
|
||||
while(k && ((k % 10LL) == 0LL || (k % 10LL) == 9LL))
|
||||
while( k && ( ( k % 10LL ) == 0LL || ( k % 10LL ) == 9LL ) )
|
||||
{
|
||||
k /= 10LL;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
|
||||
while (k != 0LL)
|
||||
while( k != 0LL )
|
||||
{
|
||||
n++;
|
||||
k /= 10LL;
|
||||
|
@ -111,64 +119,66 @@ static int countDecimalDigits ( double x, int maxDigits )
|
|||
}
|
||||
|
||||
|
||||
static void formatSILabels( mpScaleBase *scale, const wxString& aUnit, int nDigits )
|
||||
static void formatSILabels( mpScaleBase* scale, const wxString& aUnit, int nDigits )
|
||||
{
|
||||
double maxVis = scale->AbsVisibleMaxValue();
|
||||
|
||||
wxString suffix;
|
||||
int power, digits = 0;
|
||||
|
||||
getSISuffix( maxVis, aUnit, power, suffix);
|
||||
getSISuffix( maxVis, aUnit, power, suffix );
|
||||
|
||||
double sf = pow(10.0, power);
|
||||
double sf = pow( 10.0, power );
|
||||
|
||||
for ( auto &l : scale->TickLabels() )
|
||||
for( auto &l : scale->TickLabels() )
|
||||
{
|
||||
int k = countDecimalDigits( l.pos / sf, nDigits );
|
||||
|
||||
digits = std::max(digits, k);
|
||||
digits = std::max( digits, k );
|
||||
}
|
||||
|
||||
for ( auto &l : scale->TickLabels() )
|
||||
for( auto &l : scale->TickLabels() )
|
||||
{
|
||||
l.label = formatFloat ( l.pos / sf, digits ) + suffix;
|
||||
l.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class FREQUENCY_LOG_SCALE : public mpScaleXLog
|
||||
{
|
||||
public:
|
||||
FREQUENCY_LOG_SCALE(wxString name, int flags) :
|
||||
FREQUENCY_LOG_SCALE( wxString name, int flags ) :
|
||||
mpScaleXLog( name, flags ) {};
|
||||
|
||||
void formatLabels()
|
||||
{
|
||||
const wxString unit = wxT("Hz");
|
||||
const wxString unit = wxT( "Hz" );
|
||||
wxString suffix;
|
||||
int power;
|
||||
|
||||
for ( auto &l : TickLabels() )
|
||||
for( auto &l : TickLabels() )
|
||||
{
|
||||
getSISuffix( l.pos, unit, power, suffix);
|
||||
double sf = pow(10.0, power);
|
||||
getSISuffix( l.pos, unit, power, suffix );
|
||||
double sf = pow( 10.0, power );
|
||||
int k = countDecimalDigits( l.pos / sf, 3 );
|
||||
|
||||
l.label = formatFloat ( l.pos / sf, k ) + suffix;
|
||||
l.label = formatFloat( l.pos / sf, k ) + suffix;
|
||||
l.visible = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FREQUENCY_LIN_SCALE : public mpScaleX
|
||||
{
|
||||
public:
|
||||
FREQUENCY_LIN_SCALE(wxString name, int flags) :
|
||||
FREQUENCY_LIN_SCALE( wxString name, int flags ) :
|
||||
mpScaleX( name, flags, false , 0 ) {};
|
||||
|
||||
void formatLabels()
|
||||
{
|
||||
formatSILabels( this, wxT("Hz"), 3 );
|
||||
formatSILabels( this, wxT( "Hz" ), 3 );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -176,74 +186,78 @@ public:
|
|||
class TIME_SCALE : public mpScaleX
|
||||
{
|
||||
public:
|
||||
TIME_SCALE(wxString name, int flags) :
|
||||
mpScaleX ( name, flags, false, 0) {};
|
||||
TIME_SCALE( wxString name, int flags ) :
|
||||
mpScaleX( name, flags, false, 0 ) {};
|
||||
|
||||
void formatLabels()
|
||||
{
|
||||
formatSILabels( this, wxT("s"), 3 );
|
||||
formatSILabels( this, wxT( "s" ), 3 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class VOLTAGE_SCALE_X : public mpScaleX
|
||||
{
|
||||
public:
|
||||
VOLTAGE_SCALE_X(wxString name, int flags) :
|
||||
mpScaleX ( name, flags, false, 0 ) {};
|
||||
VOLTAGE_SCALE_X( wxString name, int flags ) :
|
||||
mpScaleX( name, flags, false, 0 ) {};
|
||||
|
||||
void formatLabels()
|
||||
{
|
||||
formatSILabels( this, wxT("V"), 3 );
|
||||
formatSILabels( this, wxT( "V" ), 3 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class GAIN_SCALE : public mpScaleY
|
||||
{
|
||||
public:
|
||||
GAIN_SCALE( wxString name, int flags ) :
|
||||
mpScaleY ( name, flags, false) {};
|
||||
mpScaleY( name, flags, false ) {};
|
||||
|
||||
void formatLabels()
|
||||
{
|
||||
formatSILabels( this, wxT("dB"), 3 );
|
||||
formatSILabels( this, wxT( "dB" ), 3 );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PHASE_SCALE : public mpScaleY
|
||||
{
|
||||
public:
|
||||
PHASE_SCALE(wxString name, int flags) :
|
||||
mpScaleY ( name, flags, false ) {};
|
||||
PHASE_SCALE( wxString name, int flags ) :
|
||||
mpScaleY( name, flags, false ) {};
|
||||
|
||||
void formatLabels()
|
||||
{
|
||||
formatSILabels( this, wxT("\u00B0"), 3 );
|
||||
formatSILabels( this, wxT( "\u00B0" ), 3 ); // degree sign
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class VOLTAGE_SCALE_Y : public mpScaleY
|
||||
{
|
||||
public:
|
||||
VOLTAGE_SCALE_Y(wxString name, int flags) :
|
||||
mpScaleY ( name, flags, false ) {};
|
||||
VOLTAGE_SCALE_Y( wxString name, int flags ) :
|
||||
mpScaleY( name, flags, false ) {};
|
||||
|
||||
void formatLabels()
|
||||
{
|
||||
formatSILabels( this, wxT("V"), 3 );
|
||||
formatSILabels( this, wxT( "V" ), 3 );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class CURRENT_SCALE : public mpScaleY
|
||||
{
|
||||
public:
|
||||
CURRENT_SCALE(wxString name, int flags ) :
|
||||
mpScaleY ( name, flags, false ) {};
|
||||
CURRENT_SCALE( wxString name, int flags ) :
|
||||
mpScaleY( name, flags, false ) {};
|
||||
|
||||
void formatLabels()
|
||||
{
|
||||
formatSILabels( this, wxT("A"), 3 );
|
||||
formatSILabels( this, wxT( "A" ), 3 );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -366,7 +380,7 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
|||
m_axis_x = new FREQUENCY_LOG_SCALE( wxT( "Frequency" ), mpALIGN_BOTTOM );
|
||||
m_axis_y1 = new GAIN_SCALE( wxT( "Gain" ), mpALIGN_LEFT );
|
||||
m_axis_y2 = new PHASE_SCALE( wxT( "Phase" ), mpALIGN_RIGHT );
|
||||
m_axis_y2->SetMasterScale(m_axis_y1);
|
||||
m_axis_y2->SetMasterScale( m_axis_y1 );
|
||||
break;
|
||||
|
||||
case ST_DC:
|
||||
|
@ -383,7 +397,7 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
|||
m_axis_x = new TIME_SCALE( wxT( "Time" ), mpALIGN_BOTTOM );
|
||||
m_axis_y1 = new VOLTAGE_SCALE_Y( wxT( "Voltage" ), mpALIGN_LEFT );
|
||||
m_axis_y2 = new CURRENT_SCALE( wxT( "Current" ), mpALIGN_RIGHT );
|
||||
m_axis_y2->SetMasterScale(m_axis_y1);
|
||||
m_axis_y2->SetMasterScale( m_axis_y1 );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -416,9 +430,9 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
|||
m_legend = new mpInfoLegend( wxRect( 0, 40, 200, 40 ), wxTRANSPARENT_BRUSH );
|
||||
AddLayer( m_legend );
|
||||
m_topLevel.push_back( m_legend );
|
||||
SetColourTheme(*wxBLACK, *wxWHITE, grey);
|
||||
SetColourTheme( *wxBLACK, *wxWHITE, grey );
|
||||
|
||||
EnableDoubleBuffer(true);
|
||||
EnableDoubleBuffer( true );
|
||||
UpdateAll();
|
||||
}
|
||||
|
||||
|
@ -455,20 +469,20 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
|
|||
|
||||
if( addedNewEntry )
|
||||
{
|
||||
if ( m_type == ST_TRANSIENT )
|
||||
if( m_type == ST_TRANSIENT )
|
||||
{
|
||||
bool hasVoltageTraces = false;
|
||||
|
||||
for( auto t : m_traces )
|
||||
{
|
||||
if ( ! (t.second->GetFlags() & SPT_CURRENT ) )
|
||||
if( !( t.second->GetFlags() & SPT_CURRENT ) )
|
||||
{
|
||||
hasVoltageTraces = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !hasVoltageTraces )
|
||||
if( !hasVoltageTraces )
|
||||
m_axis_y2->SetMasterScale( nullptr );
|
||||
else
|
||||
m_axis_y2->SetMasterScale( m_axis_y1 );
|
||||
|
@ -499,12 +513,12 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
|
|||
{
|
||||
if( aFlags & SPT_AC_PHASE )
|
||||
{
|
||||
for(int i = 0; i < aPoints; i++ )
|
||||
for( int i = 0; i < aPoints; i++ )
|
||||
tmp[i] = tmp[i] * 180.0 / M_PI; // convert to degrees
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < aPoints; i++ )
|
||||
for( int i = 0; i < aPoints; i++ )
|
||||
tmp[i] = 20 * log( tmp[i] ) / log( 10.0 ); // convert to dB
|
||||
}
|
||||
}
|
||||
|
@ -553,6 +567,7 @@ void SIM_PLOT_PANEL::DeleteAllTraces()
|
|||
DeleteTrace( t.first );
|
||||
}
|
||||
|
||||
m_colorIdx = 0;
|
||||
m_traces.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
class TRACE;
|
||||
|
||||
///> Cursor attached to a trace to follow its values:
|
||||
class CURSOR : public mpInfoLayer
|
||||
{
|
||||
public:
|
||||
|
@ -86,14 +87,18 @@ class TRACE : public mpFXYVector
|
|||
{
|
||||
public:
|
||||
TRACE( const wxString& aName ) :
|
||||
mpFXYVector( aName ), m_cursor( nullptr ), m_flags(0)
|
||||
{
|
||||
SetContinuity( true );
|
||||
SetDrawOutsideMargins( false );
|
||||
ShowName( false );
|
||||
|
||||
}
|
||||
mpFXYVector( aName ), m_cursor( nullptr ), m_flags( 0 )
|
||||
{
|
||||
SetContinuity( true );
|
||||
SetDrawOutsideMargins( false );
|
||||
ShowName( false );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assigns new data set for the trace. aX and aY need to have the same length.
|
||||
* @param aX are the X axis values.
|
||||
* @param aY are the Y axis values.
|
||||
*/
|
||||
void SetData( const std::vector<double>& aX, const std::vector<double>& aY ) override
|
||||
{
|
||||
if( m_cursor )
|
||||
|
@ -127,7 +132,7 @@ public:
|
|||
return m_cursor;
|
||||
}
|
||||
|
||||
void SetFlags ( int aFlags )
|
||||
void SetFlags( int aFlags )
|
||||
{
|
||||
m_flags = aFlags;
|
||||
}
|
||||
|
@ -222,26 +227,20 @@ public:
|
|||
return m_legend->IsVisible();
|
||||
}
|
||||
|
||||
void ShowCoords( bool aEnable )
|
||||
{
|
||||
m_coords->SetVisible( aEnable );
|
||||
UpdateAll();
|
||||
}
|
||||
|
||||
bool IsCoordsShown() const
|
||||
{
|
||||
return m_coords->IsVisible();
|
||||
}
|
||||
|
||||
///> Returns true if the trace has cursor shown.
|
||||
bool HasCursorEnabled( const wxString& aName ) const;
|
||||
|
||||
///> Toggles cursor for a particular trace.
|
||||
void EnableCursor( const wxString& aName, bool aEnable );
|
||||
|
||||
///> Resets scale ranges to fit the current traces
|
||||
void ResetScales();
|
||||
|
||||
private:
|
||||
///> Returns a new color from the palette
|
||||
wxColour generateColor();
|
||||
|
||||
// Color index to get a new color from the palette
|
||||
unsigned int m_colorIdx;
|
||||
|
||||
// Traces to be plotted
|
||||
|
@ -251,7 +250,6 @@ private:
|
|||
mpScaleY* m_axis_y1;
|
||||
mpScaleY* m_axis_y2;
|
||||
mpInfoLegend* m_legend;
|
||||
mpInfoCoords* m_coords;
|
||||
|
||||
std::vector<mpLayer*> m_topLevel;
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ enum SIM_PLOT_TYPE {
|
|||
SPT_AC_PHASE = 0x04,
|
||||
SPT_AC_MAG = 0x08,
|
||||
|
||||
// X axis
|
||||
SPT_TIME = 0x10,
|
||||
SPT_LIN_FREQUENCY = 0x20,
|
||||
SPT_LOG_FREQUENCY = 0x20,
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#include <schframe.h>
|
||||
|
||||
void SCH_EDIT_FRAME::OnSimulationRun( wxCommandEvent& event )
|
||||
{}
|
||||
|
||||
void SCH_EDIT_FRAME::OnSimulationStop( wxCommandEvent& event )
|
||||
{}
|
||||
|
||||
void SCH_EDIT_FRAME::OnSimulationAddProbe( wxCommandEvent& event )
|
||||
{}
|
||||
|
|
@ -41,31 +41,91 @@ public:
|
|||
SPICE_SIMULATOR() : m_reporter( NULL ) {}
|
||||
virtual ~SPICE_SIMULATOR() {}
|
||||
|
||||
///> Creates a simulator instance of particular type (currently only ngspice is handled)
|
||||
static SPICE_SIMULATOR* CreateInstance( const std::string& aName );
|
||||
|
||||
///> Intializes the simulator
|
||||
virtual void Init() = 0;
|
||||
|
||||
/*
|
||||
* @brief Loads a netlist for the simulation.
|
||||
* @return True in case of success, false otherwise.
|
||||
*/
|
||||
virtual bool LoadNetlist( const std::string& aNetlist ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Executes the simulation with currently loaded netlist.
|
||||
* @return True in case of success, false otherwise.
|
||||
*/
|
||||
virtual bool Run() = 0;
|
||||
|
||||
/**
|
||||
* @brief Halts the simulation.
|
||||
* @return True in case of success, false otherwise.
|
||||
*/
|
||||
virtual bool Stop() = 0;
|
||||
|
||||
/**
|
||||
* @brief Checks if simulation is running at the moment.
|
||||
* @return True if simulation is currently executed.
|
||||
*/
|
||||
virtual bool IsRunning() = 0;
|
||||
|
||||
/**
|
||||
* @brief Executes a Spice command as if it was typed into console.
|
||||
* @param aCmd is the command to be issued.
|
||||
*/
|
||||
virtual bool Command( const std::string& aCmd ) = 0;
|
||||
|
||||
///> Returns X axis name for a given simulation type
|
||||
virtual std::string GetXAxis( SIM_TYPE aType ) const = 0;
|
||||
|
||||
///> Sets a SPICE_REPORTER object to receive the simulation log.
|
||||
virtual void SetReporter( SPICE_REPORTER* aReporter )
|
||||
{
|
||||
m_reporter = aReporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a requested vector with complex values. If the vector is real, then
|
||||
* the imaginary part is set to 0 in all values.
|
||||
* @param aName is the vector named in Spice convention (e.g. V(3), I(R1)).
|
||||
* @return Requested vector. It might be empty if there is no vector with requested name.
|
||||
*/
|
||||
virtual std::vector<COMPLEX> GetPlot( const std::string& aName, int aMaxLen = -1 ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns a requested vector with real values. If the vector is complex, then
|
||||
* the real part is returned.
|
||||
* @param aName is the vector named in Spice convention (e.g. V(3), I(R1)).
|
||||
* @return Requested vector. It might be empty if there is no vector with requested name.
|
||||
*/
|
||||
virtual std::vector<double> GetRealPlot( const std::string& aName, int aMaxLen = -1 ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns a requested vector with imaginary values. If the vector is complex, then
|
||||
* the imaginary part is returned. If the vector is reql, then only zeroes are returned.
|
||||
* @param aName is the vector named in Spice convention (e.g. V(3), I(R1)).
|
||||
* @return Requested vector. It might be empty if there is no vector with requested name.
|
||||
*/
|
||||
virtual std::vector<double> GetImagPlot( const std::string& aName, int aMaxLen = -1 ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns a requested vector with magnitude values.
|
||||
* @param aName is the vector named in Spice convention (e.g. V(3), I(R1)).
|
||||
* @return Requested vector. It might be empty if there is no vector with requested name.
|
||||
*/
|
||||
virtual std::vector<double> GetMagPlot( const std::string& aName, int aMaxLen = -1 ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns a requested vector with phase values.
|
||||
* @param aName is the vector named in Spice convention (e.g. V(3), I(R1)).
|
||||
* @return Requested vector. It might be empty if there is no vector with requested name.
|
||||
*/
|
||||
virtual std::vector<double> GetPhasePlot( const std::string& aName, int aMaxLen = -1 ) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
///> Reporter object to receive simulation log
|
||||
SPICE_REPORTER* m_reporter;
|
||||
};
|
||||
|
||||
|
|
|
@ -221,13 +221,13 @@ SPICE_VALUE SPICE_VALUE::operator/( const SPICE_VALUE& aOther ) const
|
|||
|
||||
void SPICE_VALUE::stripZeros( wxString& aString )
|
||||
{
|
||||
if ( aString.Find(',') >= 0 || aString.Find('.') >= 0 )
|
||||
if ( aString.Find( ',' ) >= 0 || aString.Find( '.' ) >= 0 )
|
||||
{
|
||||
while( aString.EndsWith( '0' ) )
|
||||
aString.RemoveLast();
|
||||
|
||||
if( aString.EndsWith( '.' ) || aString.EndsWith( ',' ) )
|
||||
aString.RemoveLast();
|
||||
aString.RemoveLast();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
///> Parses the string to create a Spice value (e.g. 100n)
|
||||
SPICE_VALUE( const wxString& aString );
|
||||
|
||||
SPICE_VALUE( int aInt, UNIT_PREFIX aPrefix = PFX_NONE )
|
||||
|
@ -65,19 +66,35 @@ public:
|
|||
Normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Normalizes the value. The unit prefix is picked so the base is (0.001 <= base < 1000).
|
||||
*/
|
||||
void Normalize();
|
||||
|
||||
double ToDouble() const;
|
||||
|
||||
/**
|
||||
* @brief Returns string value as when converting double to string (e.g. 123456.789).
|
||||
*/
|
||||
wxString ToString() const;
|
||||
|
||||
/**
|
||||
* @brief Returns string value in Spice format (e.g. 123.3456789k).
|
||||
*/
|
||||
wxString ToSpiceString() const;
|
||||
|
||||
/**
|
||||
* @brief Returns either a normal string or Spice format string, depending on the original
|
||||
* value format.
|
||||
*/
|
||||
wxString ToOrigString() const
|
||||
{
|
||||
return m_spiceStr ? ToSpiceString() : ToString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the object was initiated with a Spice formatted string value.
|
||||
*/
|
||||
bool IsSpiceString() const
|
||||
{
|
||||
return m_spiceStr;
|
||||
|
@ -120,6 +137,7 @@ private:
|
|||
///> Was the value defined using the Spice notation?
|
||||
bool m_spiceStr;
|
||||
|
||||
///> Removes redundant zeros from the end of a string.
|
||||
static void stripZeros( wxString& aString );
|
||||
};
|
||||
|
||||
|
@ -141,6 +159,7 @@ public:
|
|||
bool Validate( wxWindow* aParent ) override;
|
||||
|
||||
private:
|
||||
///> Is it valid to get an empty value?
|
||||
bool m_emptyAllowed;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue