diff --git a/eeschema/dialogs/dialog_sim_command.cpp b/eeschema/dialogs/dialog_sim_command.cpp index a68f38782c..7ef066d20d 100644 --- a/eeschema/dialogs/dialog_sim_command.cpp +++ b/eeschema/dialogs/dialog_sim_command.cpp @@ -123,6 +123,41 @@ DIALOG_SIM_COMMAND::DIALOG_SIM_COMMAND( wxWindow* aParent, SetupStandardButtons(); } +bool DIALOG_SIM_COMMAND::TransferDataToWindow() +{ + /// @todo one day it could interpret the sim command and fill out appropriate fields. + if( empty( m_customTxt ) ) + loadDirectives(); + + m_fixIncludePaths->SetValue( m_settings->GetFixIncludePaths() ); + + NGSPICE_SIMULATOR_SETTINGS* ngspiceSettings = + dynamic_cast( m_settings.get() ); + + if( ngspiceSettings ) + { + switch( ngspiceSettings->GetModelMode() ) + { + case NGSPICE_MODEL_MODE::USER_CONFIG: m_compatibilityModeChoice->SetSelection( 0 ); break; + case NGSPICE_MODEL_MODE::NGSPICE: m_compatibilityModeChoice->SetSelection( 1 ); break; + case NGSPICE_MODEL_MODE::PSPICE: m_compatibilityModeChoice->SetSelection( 2 ); break; + case NGSPICE_MODEL_MODE::LTSPICE: m_compatibilityModeChoice->SetSelection( 3 ); break; + case NGSPICE_MODEL_MODE::LT_PSPICE: m_compatibilityModeChoice->SetSelection( 4 ); break; + case NGSPICE_MODEL_MODE::HSPICE: m_compatibilityModeChoice->SetSelection( 5 ); break; + default: + wxFAIL_MSG( wxString::Format( "Unknown NGSPICE_MODEL_MODE %d.", + ngspiceSettings->GetModelMode() ) ); + break; + } + } + + if( m_simCommand.IsEmpty() && !empty( m_customTxt ) ) + parseCommand( m_customTxt->GetValue() ); + + return true; +} + + wxString DIALOG_SIM_COMMAND::evaluateDCControls( wxChoice* aDcSource, wxTextCtrl* aDcStart, wxTextCtrl* aDcStop, wxTextCtrl* aDcIncr ) { @@ -241,14 +276,15 @@ bool DIALOG_SIM_COMMAND::TransferDataFromWindow() if( !ref.IsEmpty() ) ref = wxS( "," ) + m_circuitModel->GetItemName( std::string( ref.ToUTF8() ) ); - m_simCommand.Printf( ".noise v(%s%s) %s %s %s %s %s", + m_simCommand.Printf( ".noise v(%s%s) %s %s %s %s %s %s", output, ref, noiseSource, scaleToString( m_noiseScale->GetSelection() ), m_noisePointsNumber->GetValue(), SPICE_VALUE( m_noiseFreqStart->GetValue() ).ToSpiceString(), - SPICE_VALUE( m_noiseFreqStop->GetValue() ).ToSpiceString() ); + SPICE_VALUE( m_noiseFreqStop->GetValue() ).ToSpiceString(), + m_saveAllNoise->GetValue() ? "1" : "" ); } else if( page == m_pgOP ) // DC operating point analysis { @@ -330,41 +366,6 @@ bool DIALOG_SIM_COMMAND::TransferDataFromWindow() } -bool DIALOG_SIM_COMMAND::TransferDataToWindow() -{ - /// @todo one day it could interpret the sim command and fill out appropriate fields. - if( empty( m_customTxt ) ) - loadDirectives(); - - m_fixIncludePaths->SetValue( m_settings->GetFixIncludePaths() ); - - NGSPICE_SIMULATOR_SETTINGS* ngspiceSettings = - dynamic_cast( m_settings.get() ); - - if( ngspiceSettings ) - { - switch( ngspiceSettings->GetModelMode() ) - { - case NGSPICE_MODEL_MODE::USER_CONFIG: m_compatibilityModeChoice->SetSelection( 0 ); break; - case NGSPICE_MODEL_MODE::NGSPICE: m_compatibilityModeChoice->SetSelection( 1 ); break; - case NGSPICE_MODEL_MODE::PSPICE: m_compatibilityModeChoice->SetSelection( 2 ); break; - case NGSPICE_MODEL_MODE::LTSPICE: m_compatibilityModeChoice->SetSelection( 3 ); break; - case NGSPICE_MODEL_MODE::LT_PSPICE: m_compatibilityModeChoice->SetSelection( 4 ); break; - case NGSPICE_MODEL_MODE::HSPICE: m_compatibilityModeChoice->SetSelection( 5 ); break; - default: - wxFAIL_MSG( wxString::Format( "Unknown NGSPICE_MODEL_MODE %d.", - ngspiceSettings->GetModelMode() ) ); - break; - } - } - - if( m_simCommand.IsEmpty() && !empty( m_customTxt ) ) - parseCommand( m_customTxt->GetValue() ); - - return true; -} - - void DIALOG_SIM_COMMAND::updateDCSources( wxChar aType, wxChoice* aSource ) { wxString prevSelection; @@ -485,9 +486,10 @@ void DIALOG_SIM_COMMAND::parseCommand( const wxString& aCommand ) SPICE_VALUE pts; SPICE_VALUE fStart; SPICE_VALUE fStop; + bool saveAll; m_circuitModel->ParseNoiseCommand( aCommand, &output, &ref, &source, &scale, &pts, - &fStart, &fStop ); + &fStart, &fStop, &saveAll ); m_noiseMeas->SetStringSelection( output ); m_noiseRef->SetStringSelection( ref ); @@ -505,6 +507,8 @@ void DIALOG_SIM_COMMAND::parseCommand( const wxString& aCommand ) m_noisePointsNumber->SetValue( pts.ToSpiceString() ); m_noiseFreqStart->SetValue( fStart.ToSpiceString() ); m_noiseFreqStop->SetValue( fStop.ToSpiceString() ); + + m_saveAllNoise->SetValue( saveAll ); } else if( token == ".tran" ) { diff --git a/eeschema/dialogs/dialog_sim_command_base.cpp b/eeschema/dialogs/dialog_sim_command_base.cpp index df5894c496..3b2f87b5d5 100644 --- a/eeschema/dialogs/dialog_sim_command_base.cpp +++ b/eeschema/dialogs/dialog_sim_command_base.cpp @@ -312,11 +312,14 @@ DIALOG_SIM_COMMAND_BASE::DIALOG_SIM_COMMAND_BASE( wxWindow* parent, wxWindowID i fgSizer11->Add( m_noiseFreqStopUnits, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - bSizer10->Add( fgSizer11, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT, 5 ); + bSizer10->Add( fgSizer11, 0, wxALIGN_BOTTOM|wxTOP|wxLEFT, 5 ); bSizer15->Add( bSizer10, 0, wxEXPAND|wxTOP, 5 ); + m_saveAllNoise = new wxCheckBox( m_pgNoise, wxID_ANY, _("Save contributions from all noise generators"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer15->Add( m_saveAllNoise, 0, wxALL, 10 ); + m_pgNoise->SetSizer( bSizer15 ); m_pgNoise->Layout(); diff --git a/eeschema/dialogs/dialog_sim_command_base.fbp b/eeschema/dialogs/dialog_sim_command_base.fbp index b143e9312b..00d2eb4fd5 100644 --- a/eeschema/dialogs/dialog_sim_command_base.fbp +++ b/eeschema/dialogs/dialog_sim_command_base.fbp @@ -3113,7 +3113,7 @@ 5 - wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT + wxALIGN_BOTTOM|wxTOP|wxLEFT 0 3 @@ -3638,6 +3638,70 @@ + + 10 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Save contributions from all noise generators + + 0 + + + 0 + + 1 + m_saveAllNoise + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + diff --git a/eeschema/dialogs/dialog_sim_command_base.h b/eeschema/dialogs/dialog_sim_command_base.h index 1e683cea1a..3c0be70970 100644 --- a/eeschema/dialogs/dialog_sim_command_base.h +++ b/eeschema/dialogs/dialog_sim_command_base.h @@ -97,6 +97,7 @@ class DIALOG_SIM_COMMAND_BASE : public DIALOG_SHIM wxStaticText* m_staticText31; wxTextCtrl* m_noiseFreqStop; wxStaticText* m_noiseFreqStopUnits; + wxCheckBox* m_saveAllNoise; wxPanel* m_pgOP; wxStaticText* m_staticText13; wxPanel* m_pgPoleZero; diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h index 606fa590a6..6b40066848 100644 --- a/eeschema/eeschema_id.h +++ b/eeschema/eeschema_id.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2008 Wayne Stambaugh - * Copyright (C) 2008-2021 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2008-2023 KiCad Developers, see change_log.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 @@ -28,14 +28,6 @@ #include -/** - * The maximum number of items in the clarify selection context menu. While in - * most cases it is highly unlikely that there would ever be more than 10 items - * at the current cursor, there are some exceptions (a bunch of pins created at - * once, for instance). The current setting of 200 is arbitrary. - */ -#define MAX_SELECT_ITEM_IDS 200 - /** * The maximum number of units per package. * While counts approaching 100 start to make the unit-selection popup menu @@ -75,11 +67,6 @@ enum id_eeschema_frm ID_LIBVIEW_SYM_FILTER, ID_LIBVIEW_SYM_LIST, - ID_SIM_RUN, - ID_SIM_TUNE, - ID_SIM_PROBE, - ID_SIM_ADD_SIGNALS, - ID_END_EESCHEMA_ID_LIST, // End of IDs specific to Eeschema // These ID are used in context menus, diff --git a/eeschema/sim/ngspice.cpp b/eeschema/sim/ngspice.cpp index 918df09b82..ef1081956b 100644 --- a/eeschema/sim/ngspice.cpp +++ b/eeschema/sim/ngspice.cpp @@ -84,25 +84,25 @@ void NGSPICE::Init( const SPICE_SIMULATOR_SETTINGS* aSettings ) } -std::vector NGSPICE::AllPlots() const +std::vector NGSPICE::AllVectors() const { LOCALE_IO c_locale; // ngspice works correctly only with C locale char* currentPlot = m_ngSpice_CurPlot(); - char** allPlots = m_ngSpice_AllVecs( currentPlot ); - int noOfPlots = 0; + char** allVectors = m_ngSpice_AllVecs( currentPlot ); + int noOfVectors = 0; std::vector retVal; - if( allPlots != nullptr ) + if( allVectors != nullptr ) { - for( char** plot = allPlots; *plot != nullptr; plot++ ) - noOfPlots++; + for( char** plot = allVectors; *plot != nullptr; plot++ ) + noOfVectors++; - retVal.reserve( noOfPlots ); + retVal.reserve( noOfVectors ); - for( int i = 0; i < noOfPlots; i++, allPlots++ ) + for( int i = 0; i < noOfVectors; i++, allVectors++ ) { - std::string vec = *allPlots; + std::string vec = *allVectors; retVal.push_back( vec ); } } @@ -336,10 +336,10 @@ wxString NGSPICE::GetXAxis( SIM_TYPE aType ) const case ST_DC: // find plot, which ends with "-sweep" - for( wxString plot : AllPlots() ) + for( wxString vector : AllVectors() ) { - if( plot.Lower().EndsWith( wxS( "-sweep" ) ) ) - return plot; + if( vector.Lower().EndsWith( wxS( "-sweep" ) ) ) + return vector; } return wxS( "sweep" ); diff --git a/eeschema/sim/ngspice.h b/eeschema/sim/ngspice.h index c1179d6713..9a9cc04e82 100644 --- a/eeschema/sim/ngspice.h +++ b/eeschema/sim/ngspice.h @@ -80,8 +80,8 @@ public: ///< @copydoc SPICE_SIMULATOR::GetXAxis() wxString GetXAxis( SIM_TYPE aType ) const override final; - ///< @copydoc SPICE_SIMULATOR::AllPlots() - std::vector AllPlots() const override final; + ///< @copydoc SPICE_SIMULATOR::AllVectors() + std::vector AllVectors() const override final; ///< @copydoc SPICE_SIMULATOR::GetPlot() std::vector GetPlot( const std::string& aName, int aMaxLen = -1 ) override final; diff --git a/eeschema/sim/ngspice_circuit_model.cpp b/eeschema/sim/ngspice_circuit_model.cpp index b1f91d2112..58157dd6b4 100644 --- a/eeschema/sim/ngspice_circuit_model.cpp +++ b/eeschema/sim/ngspice_circuit_model.cpp @@ -147,7 +147,7 @@ bool NGSPICE_CIRCUIT_MODEL::ParseDCCommand( const wxString& aCmd, SPICE_DC_PARAM bool NGSPICE_CIRCUIT_MODEL::ParseNoiseCommand( const wxString& aCmd, wxString* aOutput, wxString* aRef, wxString* aSource, wxString* aScale, SPICE_VALUE* aPts, SPICE_VALUE* aFStart, - SPICE_VALUE* aFStop ) + SPICE_VALUE* aFStop, bool* aSaveAll ) { if( !aCmd.Lower().StartsWith( wxS( ".noise" ) ) ) return false; @@ -197,7 +197,13 @@ bool NGSPICE_CIRCUIT_MODEL::ParseNoiseCommand( const wxString& aCmd, wxString* a } if( !token.IsEmpty() ) + { *aFStop = SPICE_VALUE( token ); + token = tokens.GetNextToken(); + } + + if( !token.IsEmpty() ) + *aSaveAll = true; return true; } diff --git a/eeschema/sim/ngspice_circuit_model.h b/eeschema/sim/ngspice_circuit_model.h index a58d1e1ada..45bf1adfeb 100644 --- a/eeschema/sim/ngspice_circuit_model.h +++ b/eeschema/sim/ngspice_circuit_model.h @@ -129,7 +129,7 @@ public: bool ParseNoiseCommand( const wxString& aCmd, wxString* aOutput, wxString* aRef, wxString* aSource, wxString* aScale, SPICE_VALUE* aPts, - SPICE_VALUE* aFStart, SPICE_VALUE* aFStop ); + SPICE_VALUE* aFStart, SPICE_VALUE* aFStop, bool* aSaveAll ); /** * Determine if a directive is a simulation command. diff --git a/eeschema/sim/simulator_frame.cpp b/eeschema/sim/simulator_frame.cpp index 38f607b71a..a8b0f9a6e9 100644 --- a/eeschema/sim/simulator_frame.cpp +++ b/eeschema/sim/simulator_frame.cpp @@ -427,7 +427,7 @@ void SIMULATOR_FRAME::NewPlotPanel( const wxString& aSimCommand, int aOptions ) } -const std::vector& SIMULATOR_FRAME::Signals() +const std::vector SIMULATOR_FRAME::Signals() { return m_panel->Signals(); } diff --git a/eeschema/sim/simulator_frame.h b/eeschema/sim/simulator_frame.h index 8bcdebf000..1c825f868c 100644 --- a/eeschema/sim/simulator_frame.h +++ b/eeschema/sim/simulator_frame.h @@ -95,7 +95,10 @@ public: */ bool EditSimCommand(); - const std::vector& Signals(); + /** + * @return the list of signals in the current simulation results. + */ + const std::vector Signals(); const std::map& UserDefinedSignals(); diff --git a/eeschema/sim/simulator_panel.cpp b/eeschema/sim/simulator_panel.cpp index d14fc09b75..717e66332f 100644 --- a/eeschema/sim/simulator_panel.cpp +++ b/eeschema/sim/simulator_panel.cpp @@ -741,8 +741,8 @@ void SIMULATOR_PANEL::rebuildSignalsList() if( simType == ST_NOISE ) { - addSignal( wxS( "inoise" ) ); - addSignal( wxS( "onoise" ) ); + addSignal( wxS( "inoise_spectrum" ) ); + addSignal( wxS( "onoise_spectrum" ) ); } // Add .PROBE directives @@ -847,18 +847,16 @@ wxString SIMULATOR_PANEL::vectorNameFromSignalName( const wxString& aSignalName, if( aTraceType ) { - wxString name = aSignalName.Upper(); - - if( name == wxS( "INOISE" ) || name == wxS( "ONOISE" ) ) + if( circuitModel()->GetSimType() == ST_NOISE ) { if( getNoiseSource().Upper().StartsWith( 'I' ) ) *aTraceType = SPT_CURRENT; else *aTraceType = SPT_VOLTAGE; } - else if( !name.IsEmpty() ) + else { - wxUniChar firstChar = name[0]; + wxUniChar firstChar = aSignalName.Upper()[0]; if( firstChar == 'V' ) *aTraceType = SPT_VOLTAGE; @@ -1451,10 +1449,6 @@ void SIMULATOR_PANEL::updateTrace( const wxString& aVectorName, int aTraceType, break; case ST_NOISE: - simVectorName = wxString::Format( wxS( "noise1.%s_spectrum" ), simVectorName ); - data_y = simulator()->GetMagPlot( (const char*) simVectorName.c_str() ); - break; - case ST_DC: case ST_TRANSIENT: data_y = simulator()->GetMagPlot( (const char*) simVectorName.c_str() ); @@ -2137,9 +2131,10 @@ wxString SIMULATOR_PANEL::getNoiseSource() const SPICE_VALUE pts; SPICE_VALUE fStart; SPICE_VALUE fStop; + bool saveAll; circuitModel()->ParseNoiseCommand( circuitModel()->GetSimCommand(), &output, &ref, &source, - &scale, &pts, &fStart, &fStop ); + &scale, &pts, &fStart, &fStop, &saveAll ); return source; } @@ -2388,6 +2383,17 @@ void SIMULATOR_PANEL::OnSimReport( const wxString& aMsg ) } +std::vector SIMULATOR_PANEL::Signals() +{ + std::vector signals; + + for( const std::string& vec : simulator()->AllVectors() ) + signals.emplace_back( vec ); + + return signals; +} + + void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) { SIM_TYPE simType = circuitModel()->GetSimType(); @@ -2413,7 +2419,9 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) m_simConsole->AppendText( _( "\n\nSimulation results:\n\n" ) ); m_simConsole->SetInsertionPointEnd(); - for( const std::string& vec : simulator()->AllPlots() ) + simulator()->Command( "setplot noise2" ); + + for( const std::string& vec : simulator()->AllVectors() ) { std::vector val_list = simulator()->GetRealPlot( vec, 1 ); wxString value = SPICE_VALUE( val_list[ 0 ] ).ToSpiceString(); @@ -2423,6 +2431,8 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) m_simConsole->AppendText( msg ); m_simConsole->SetInsertionPointEnd(); } + + simulator()->Command( "setplot noise1" ); } SIM_PLOT_PANEL* plotPanel = dynamic_cast( plotPanelWindow ); @@ -2483,7 +2493,7 @@ void SIMULATOR_PANEL::OnSimRefresh( bool aFinal ) m_simConsole->AppendText( _( "\n\nSimulation results:\n\n" ) ); m_simConsole->SetInsertionPointEnd(); - for( const std::string& vec : simulator()->AllPlots() ) + for( const std::string& vec : simulator()->AllVectors() ) { std::vector val_list = simulator()->GetRealPlot( vec, 1 ); wxString value = SPICE_VALUE( val_list[ 0 ] ).ToSpiceString(); diff --git a/eeschema/sim/simulator_panel.h b/eeschema/sim/simulator_panel.h index 301bdccc22..619a59df26 100644 --- a/eeschema/sim/simulator_panel.h +++ b/eeschema/sim/simulator_panel.h @@ -91,7 +91,7 @@ public: */ SIM_PLOT_PANEL_BASE* NewPlotPanel( const wxString& aSimCommand, int aSimOptions ); - const std::vector& Signals() { return m_signals; } + std::vector Signals(); const std::map& UserDefinedSignals() { return m_userDefinedSignals; } void SetUserDefinedSignals( const std::map& aSignals ); diff --git a/eeschema/sim/spice_simulator.h b/eeschema/sim/spice_simulator.h index 3306d432a7..d3087ee0d4 100644 --- a/eeschema/sim/spice_simulator.h +++ b/eeschema/sim/spice_simulator.h @@ -91,7 +91,7 @@ public: * * @return List of vector names. ?May not match to the net name elements. */ - virtual std::vector AllPlots() const = 0; + virtual std::vector AllVectors() const = 0; /** * Return a requested vector with complex values. If the vector is real, then