Check for sheet directive changes when running simulations.

Fixes https://gitlab.com/kicad/code/kicad/issues/10486
This commit is contained in:
Jeff Young 2022-12-05 20:01:36 +00:00
parent 7e1fecaf2e
commit 8e4cd1e1a6
6 changed files with 83 additions and 101 deletions

View File

@ -1,8 +1,8 @@
/* /*
* 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-2021 CERN * Copyright (C) 2016-2022 CERN
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -100,7 +100,6 @@ DIALOG_SIM_SETTINGS::DIALOG_SIM_SETTINGS( wxWindow* aParent,
m_compatibilityMode->Show( false ); m_compatibilityMode->Show( false );
SetupStandardButtons(); SetupStandardButtons();
updateNetlistOpts();
} }
wxString DIALOG_SIM_SETTINGS::evaluateDCControls( wxChoice* aDcSource, wxTextCtrl* aDcStart, wxString DIALOG_SIM_SETTINGS::evaluateDCControls( wxChoice* aDcSource, wxTextCtrl* aDcStart,
@ -298,9 +297,7 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
if( previousSimCommand != m_simCommand ) if( previousSimCommand != m_simCommand )
m_simCommand.Trim(); m_simCommand.Trim();
updateNetlistOpts(); m_settings->SetFixIncludePaths( m_fixIncludePaths->GetValue() );
m_settings->SetFixIncludePaths( m_netlistOpts & NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS );
return true; return true;
} }
@ -313,7 +310,6 @@ bool DIALOG_SIM_SETTINGS::TransferDataToWindow()
loadDirectives(); loadDirectives();
m_fixIncludePaths->SetValue( m_settings->GetFixIncludePaths() ); m_fixIncludePaths->SetValue( m_settings->GetFixIncludePaths() );
updateNetlistOpts();
NGSPICE_SIMULATOR_SETTINGS* ngspiceSettings = NGSPICE_SIMULATOR_SETTINGS* ngspiceSettings =
dynamic_cast<NGSPICE_SIMULATOR_SETTINGS*>( m_settings.get() ); dynamic_cast<NGSPICE_SIMULATOR_SETTINGS*>( m_settings.get() );
@ -607,10 +603,3 @@ void DIALOG_SIM_SETTINGS::loadDirectives()
} }
void DIALOG_SIM_SETTINGS::updateNetlistOpts()
{
m_netlistOpts = NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS;
if( !m_fixIncludePaths->IsChecked() )
m_netlistOpts &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
}

View File

@ -1,8 +1,8 @@
/* /*
* 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 CERN * Copyright (C) 2016-2022 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
@ -57,12 +57,6 @@ public:
return res; return res;
} }
int GetNetlistOptions() const
{
return m_netlistOpts;
}
bool TransferDataFromWindow() override; bool TransferDataFromWindow() override;
bool TransferDataToWindow() override; bool TransferDataToWindow() override;
@ -158,31 +152,22 @@ private:
{ {
switch( aOption ) switch( aOption )
{ {
case DECADE: case DECADE: return wxString( "dec" );
return wxString( "dec" ); case OCTAVE: return wxString( "oct" );
case LINEAR: return wxString( "lin" );
case OCTAVE: default: wxFAIL_MSG( "Unhandled scale type" ); return wxEmptyString;
return wxString( "oct" );
case LINEAR:
return wxString( "lin" );
} }
wxASSERT_MSG( false, "Unhandled scale type" );
return wxEmptyString;
} }
void loadDirectives(); void loadDirectives();
void updateNetlistOpts();
wxString m_simCommand; private:
int m_netlistOpts; wxString m_simCommand;
std::shared_ptr<NGSPICE_CIRCUIT_MODEL> m_circuitModel; std::shared_ptr<NGSPICE_CIRCUIT_MODEL> m_circuitModel;
std::shared_ptr<SPICE_SIMULATOR_SETTINGS> m_settings; std::shared_ptr<SPICE_SIMULATOR_SETTINGS> m_settings;
SPICE_VALIDATOR m_spiceValidator; SPICE_VALIDATOR m_spiceValidator;
SPICE_VALIDATOR m_spiceEmptyValidator; SPICE_VALIDATOR m_spiceEmptyValidator;
wxIntegerValidator<int> m_posIntValidator; wxIntegerValidator<int> m_posIntValidator;
}; };
#endif /* DIALOG_SIM_SETTINGS_H */ #endif /* DIALOG_SIM_SETTINGS_H */

View File

@ -1,10 +1,9 @@
/* /*
* 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 CERN * Copyright (C) 2016-2022 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.TXT for contributors. * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.TXT for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -152,6 +151,6 @@ void NGSPICE_CIRCUIT_MODEL::WriteDirectives( OUTPUTFORMATTER& aFormatter,
{ {
NETLIST_EXPORTER_SPICE::WriteDirectives( aFormatter, aNetlistOptions ); NETLIST_EXPORTER_SPICE::WriteDirectives( aFormatter, aNetlistOptions );
if( GetUnderlyingSimCommand() != "" ) if( GetSimCommandOverride() != "" )
aFormatter.Print( 0, "%s\n", TO_UTF8( GetUnderlyingSimCommand() ) ); aFormatter.Print( 0, "%s\n", TO_UTF8( GetSimCommandOverride() ) );
} }

View File

@ -1,8 +1,8 @@
/* /*
* 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 CERN * Copyright (C) 2016-2022 CERN
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
@ -77,9 +77,13 @@ public:
/** /**
* Override the simulation command directive. * Override the simulation command directive.
*/ */
void SetSimCommand( const wxString& aCmd ) void SetSimCommandOverride( const wxString& aCmd )
{ {
m_simCommand = aCmd; if( aCmd != m_simCommand )
{
m_lastSheetSimCommand = GetSheetSimCommand();
m_simCommand = aCmd;
}
} }
/** /**
@ -94,20 +98,12 @@ public:
/** /**
* Return the simulation command directive if stored separately (not as a sheet directive). * Return the simulation command directive if stored separately (not as a sheet directive).
*/ */
wxString GetUnderlyingSimCommand() const { return m_simCommand; } wxString GetSimCommandOverride() const { return m_simCommand; }
/**
* Clear the simulation command directive.
*/
void ClearSimCommand()
{
m_simCommand.Clear();
}
/** /**
* Return simulation type basing on the simulation command directives. * Return simulation type basing on the simulation command directives.
* *
* Simulation directives set using SetSimCommand() have priority over the ones placed in * Simulation directives set using SetSimCommandOverride() have priority over the ones placed in
* schematic sheets. * schematic sheets.
*/ */
SIM_TYPE GetSimType(); SIM_TYPE GetSimType();
@ -117,6 +113,13 @@ public:
*/ */
wxString GetSheetSimCommand(); wxString GetSheetSimCommand();
/**
* Return the sim command present as a sheet directive when the sim command override was last
* updated.
* @return
*/
wxString GetLastSheetSimCommand() const { return m_lastSheetSimCommand; }
/** /**
* Parse a two-source .dc command directive into its symbols. * Parse a two-source .dc command directive into its symbols.
* *
@ -145,7 +148,11 @@ protected:
private: private:
///< Custom simulation command (has priority over the schematic sheet simulation commands) ///< Custom simulation command (has priority over the schematic sheet simulation commands)
wxString m_simCommand; wxString m_simCommand;
int m_options;
///< Value of schematic sheet simulation command when override was last updated
wxString m_lastSheetSimCommand;
int m_options;
}; };
#endif /* NETLIST_EXPORTER_PSPICE_SIM_H */ #endif /* NETLIST_EXPORTER_PSPICE_SIM_H */

View File

@ -1,7 +1,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 CERN * Copyright (C) 2016-2022 CERN
* Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2022 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>
@ -155,12 +155,6 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_reporter = new SIM_THREAD_REPORTER( this ); m_reporter = new SIM_THREAD_REPORTER( this );
m_simulator->SetReporter( m_reporter ); m_simulator->SetReporter( m_reporter );
// the settings dialog will be created later, on demand.
// if created in the ctor, for some obscure reason, there is an issue
// on Windows: when open it, the simulator frame is sent to the background.
// instead of being behind the dialog frame (as it does)
m_settingsDlg = nullptr;
m_circuitModel.reset( new NGSPICE_CIRCUIT_MODEL( &m_schematicFrame->Schematic() ) ); m_circuitModel.reset( new NGSPICE_CIRCUIT_MODEL( &m_schematicFrame->Schematic() ) );
Bind( EVT_SIM_UPDATE, &SIM_PLOT_FRAME::onSimUpdate, this ); Bind( EVT_SIM_UPDATE, &SIM_PLOT_FRAME::onSimUpdate, this );
@ -249,9 +243,6 @@ SIM_PLOT_FRAME::~SIM_PLOT_FRAME()
m_simulator->SetReporter( nullptr ); m_simulator->SetReporter( nullptr );
delete m_reporter; delete m_reporter;
delete m_signalsIconColorList; delete m_signalsIconColorList;
if( m_settingsDlg )
m_settingsDlg->Destroy();
} }
@ -463,22 +454,20 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
wxCHECK_RET( m_circuitModel->CommandToSimType( getCurrentSimCommand() ) != ST_UNKNOWN, wxCHECK_RET( m_circuitModel->CommandToSimType( getCurrentSimCommand() ) != ST_UNKNOWN,
wxT( "Unknown simulation type" ) ); wxT( "Unknown simulation type" ) );
if( !m_settingsDlg )
m_settingsDlg = new DIALOG_SIM_SETTINGS( this, m_circuitModel, m_simulator->Settings() );
m_simConsole->Clear(); m_simConsole->Clear();
if( aSimCommand != wxEmptyString ) if( aSimCommand != wxEmptyString )
m_circuitModel->SetSimCommand( aSimCommand ); m_circuitModel->SetSimCommandOverride( aSimCommand );
else if( m_circuitModel->GetSheetSimCommand() != getCurrentSimCommand() )
m_circuitModel->SetSimCommand( getCurrentSimCommand() );
else
m_circuitModel->SetSimCommand( wxEmptyString );
// Make .save all and .probe alli permanent for now. // Make .save all and .probe all permanent for now.
m_circuitModel->SetOptions( m_settingsDlg->GetNetlistOptions() int options = NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS
| NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES | NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES
| NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS ); | NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
if( !m_simulator->Settings()->GetFixIncludePaths() )
options &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
m_circuitModel->SetOptions( options );
wxString errors; wxString errors;
WX_STRING_REPORTER reporter( &errors ); WX_STRING_REPORTER reporter( &errors );
@ -491,6 +480,27 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
return; return;
} }
SIM_PANEL_BASE* plotWindow = getCurrentPlotWindow();
wxString sheetSimCommand = m_circuitModel->GetSheetSimCommand();
if( plotWindow
&& plotWindow->GetType() == NGSPICE_CIRCUIT_MODEL::CommandToSimType( sheetSimCommand ) )
{
if( m_circuitModel->GetSimCommandOverride().IsEmpty() )
{
m_workbook->SetSimCommand( plotWindow, sheetSimCommand );
}
else if( sheetSimCommand != m_circuitModel->GetLastSheetSimCommand() )
{
if( IsOK( this, _( "Schematic sheet simulation command directive has changed. Do you "
"wish to update the Simulation Command?" ) ) )
{
m_circuitModel->SetSimCommandOverride( wxEmptyString );
m_workbook->SetSimCommand( plotWindow, sheetSimCommand );
}
}
}
std::unique_lock<std::mutex> simulatorLock( m_simulator->GetMutex(), std::try_to_lock ); std::unique_lock<std::mutex> simulatorLock( m_simulator->GetMutex(), std::try_to_lock );
if( simulatorLock.owns_lock() ) if( simulatorLock.owns_lock() )
@ -1477,13 +1487,10 @@ void SIM_PLOT_FRAME::onSimulate( wxCommandEvent& event )
void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event ) void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
{ {
SIM_PANEL_BASE* plotPanelWindow = getCurrentPlotWindow(); SIM_PANEL_BASE* plotPanelWindow = getCurrentPlotWindow();
DIALOG_SIM_SETTINGS dlg( this, m_circuitModel, m_simulator->Settings() );
if( !m_settingsDlg ) wxString errors;
m_settingsDlg = new DIALOG_SIM_SETTINGS( this, m_circuitModel, m_simulator->Settings() ); WX_STRING_REPORTER reporter( &errors );
wxString errors;
WX_STRING_REPORTER reporter( &errors );
if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS, if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS,
reporter ) ) reporter ) )
@ -1494,9 +1501,9 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
} }
if( m_workbook->GetPageIndex( plotPanelWindow ) != wxNOT_FOUND ) if( m_workbook->GetPageIndex( plotPanelWindow ) != wxNOT_FOUND )
m_settingsDlg->SetSimCommand( m_workbook->GetSimCommand( plotPanelWindow ) ); dlg.SetSimCommand( m_workbook->GetSimCommand( plotPanelWindow ) );
if( m_settingsDlg->ShowModal() == wxID_OK ) if( dlg.ShowModal() == wxID_OK )
{ {
wxString oldCommand; wxString oldCommand;
@ -1505,7 +1512,7 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
else else
oldCommand = wxString(); oldCommand = wxString();
wxString newCommand = m_settingsDlg->GetSimCommand(); wxString newCommand = dlg.GetSimCommand();
SIM_TYPE newSimType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( newCommand ); SIM_TYPE newSimType = NGSPICE_CIRCUIT_MODEL::CommandToSimType( newCommand );
// If it is a new simulation type, open a new plot // If it is a new simulation type, open a new plot
@ -1521,6 +1528,7 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
else else
{ {
// Update simulation command in the current plot // Update simulation command in the current plot
m_circuitModel->SetSimCommandOverride( newCommand );
m_workbook->SetSimCommand( plotPanelWindow, newCommand ); m_workbook->SetSimCommand( plotPanelWindow, newCommand );
} }

View File

@ -1,8 +1,8 @@
/* /*
* 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 CERN * Copyright (C) 2016-2022 CERN
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2017-2022 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>
@ -339,12 +339,6 @@ private:
///< List of currently displayed tuners ///< List of currently displayed tuners
std::list<TUNER_SLIDER*> m_tuners; std::list<TUNER_SLIDER*> m_tuners;
// Trick to preserve settings between runs:
// the DIALOG_SIM_SETTINGS is not destroyed after closing the dialog.
// Once created it will be not shown (shown only on request) during a session
// and will be destroyed only when closing the simulator frame.
DIALOG_SIM_SETTINGS* m_settingsDlg;
// Right click context menu for signals in the listbox // Right click context menu for signals in the listbox
class SIGNAL_CONTEXT_MENU : public wxMenu class SIGNAL_CONTEXT_MENU : public wxMenu
{ {