Initial 'Simulation settings' dialog

This commit is contained in:
Maciej Suminski 2016-08-11 14:41:29 +02:00
parent 17294aaf6a
commit a2b16ae640
14 changed files with 6757 additions and 103 deletions

View File

@ -176,12 +176,15 @@ set( EESCHEMA_SRCS
transform.cpp
viewlib_frame.cpp
viewlibs.cpp
sim/simulate.cpp
sim/sim_plot_frame_base.cpp
sim/sim_plot_frame.cpp
sim/sim_plot_panel.cpp
sim/spice_simulator.cpp
sim/ngspice.cpp
dialogs/dialog_sim_settings.cpp
dialogs/dialog_sim_settings_base.cpp
netlist_exporters/netlist_exporter.cpp
netlist_exporters/netlist_exporter_cadstar.cpp

View File

@ -0,0 +1,162 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "dialog_sim_settings.h"
#include <wx/log.h>
/// @todo ngspice offers more types of analysis,
//so there are a few tabs missing (e.g. pole-zero, distortion, sensitivity)
DIALOG_SIM_SETTINGS::DIALOG_SIM_SETTINGS( wxWindow* aParent )
: DIALOG_SIM_SETTINGS_BASE( aParent ), m_exporter( nullptr )
{
m_posFloatValidator.SetMin( 0 + std::numeric_limits<double>::epsilon() );
m_posFloatValidator.SetPrecision( 3 );
m_posIntValidator.SetMin( 1 );
m_acPointsNumber->SetValidator( m_posIntValidator );
m_acFreqStart->SetValidator( m_posFloatValidator );
m_acFreqStop->SetValidator( m_posFloatValidator );
m_dcStart1->SetValidator( m_posFloatValidator );
m_dcStop1->SetValidator( m_posFloatValidator );
m_dcIncr1->SetValidator( m_posFloatValidator );
m_dcStart2->SetValidator( m_posFloatValidator );
m_dcStop2->SetValidator( m_posFloatValidator );
m_dcIncr2->SetValidator( m_posFloatValidator );
m_noisePointsNumber->SetValidator( m_posIntValidator );
m_noiseFreqStart->SetValidator( m_posFloatValidator );
m_noiseFreqStop->SetValidator( m_posFloatValidator );
m_transStep->SetValidator( m_posFloatValidator );
m_transFinal->SetValidator( m_posFloatValidator );
m_transInitial->SetValidator( m_posFloatValidator );
}
bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
{
if( !wxDialog::TransferDataFromWindow() )
return false;
wxWindow* page = m_simPages->GetCurrentPage();
// AC analysis
if( page == m_pgAC )
{
m_simCommand = wxString::Format( ".ac %s %s %s %s",
scaleToString( m_acScale->GetSelection() ),
m_acPointsNumber->GetValue(), m_acFreqStart->GetValue(), m_acFreqStop->GetValue() );
}
// DC transfer analysis
else if( page == m_pgDC )
{
// At least one source has to be enabled
if( !m_dcEnable1->IsChecked() && !m_dcEnable1->IsChecked() )
return false;
wxString simCmd = wxString( ".dc " );
if( m_dcEnable1->IsChecked() )
{
if( m_dcSource1->GetValue().IsEmpty() )
return false;
simCmd += wxString::Format( "%s %s %s %s",
m_dcSource1->GetValue(), m_dcStart1->GetValue(),
m_dcStop1->GetValue(), m_dcIncr1->GetValue() );
}
if( m_dcEnable2->IsChecked() )
{
if( m_dcSource2->GetValue().IsEmpty() )
return false;
simCmd += wxString::Format( "%s %s %s %s",
m_dcSource2->GetValue(), m_dcStart2->GetValue(),
m_dcStop2->GetValue(), m_dcIncr2->GetValue() );
}
m_simCommand = simCmd;
}
// Noise analysis
else if( page == m_pgNoise )
{
if( m_noiseMeas->GetValue().IsEmpty() || m_noiseSrc->GetValue().IsEmpty() )
return false;
// TODO missing node number
wxString ref = m_noiseRef->GetValue().IsEmpty() ? wxString() : wxString::Format( ", %d", 42 );
m_simCommand = wxString::Format( ".noise v(%d%s) %s %s %s %s %s",
42, ref, m_noiseSrc->GetValue(), scaleToString( m_noiseScale->GetSelection() ),
m_noisePointsNumber->GetValue(), m_noiseFreqStart->GetValue(), m_noiseFreqStop->GetValue() );
}
// DC operating point analysis
else if( page == m_pgOP )
{
m_simCommand = wxString( ".op" );
}
// Transient analysis
else if( page == m_pgTransient )
{
m_simCommand = wxString::Format( ".trans %s %s %s",
m_transStep->GetValue(), m_transFinal->GetValue(), m_transInitial->GetValue() );
}
// Custom directives
else if( page == m_pgCustom )
{
m_simCommand = m_customTxt->GetValue();
}
else
{
return false;
}
return true;
}
bool DIALOG_SIM_SETTINGS::TransferDataToWindow()
{
/// @todo one day it could interpret the sim command and fill out appropriate fields..
return true;
}
void DIALOG_SIM_SETTINGS::onLoadDirectives( wxCommandEvent& event )
{
}

View File

@ -0,0 +1,87 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DIALOG_SIM_SETTINGS_BASE_H
#define DIALOG_SIM_SETTINGS_BASE_H
#include "dialog_sim_settings_base.h"
#include <wx/valnum.h>
class NETLIST_EXPORTER_PSPICE_SIM;
class DIALOG_SIM_SETTINGS : public DIALOG_SIM_SETTINGS_BASE
{
public:
DIALOG_SIM_SETTINGS( wxWindow* aParent );
const wxString& GetSimCommand() const
{
return m_simCommand;
}
void SetNetlistExporter( NETLIST_EXPORTER_PSPICE_SIM* aExporter )
{
m_exporter = aExporter;
}
bool TransferDataFromWindow() override;
bool TransferDataToWindow() override;
private:
enum SCALE_TYPE
{
DECADE,
OCTAVE,
LINEAR
};
void onLoadDirectives( wxCommandEvent& event ) override;
static wxString scaleToString( int aOption )
{
switch( aOption )
{
case DECADE:
return wxString( "dec" );
case OCTAVE:
return wxString( "oct" );
case LINEAR:
return wxString( "lin" );
}
wxASSERT_MSG( false, "Unhandled scale type" );
return wxEmptyString;
}
wxString m_simCommand;
NETLIST_EXPORTER_PSPICE_SIM* m_exporter;
wxFloatingPointValidator<double> m_posFloatValidator;
wxIntegerValidator<int> m_posIntValidator;
};
#endif /* DIALOG_SIM_SETTINGS_BASE_H */

View File

@ -0,0 +1,404 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 24 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_sim_settings_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_SIM_SETTINGS_BASE::DIALOG_SIM_SETTINGS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bSizer1;
bSizer1 = new wxBoxSizer( wxVERTICAL );
m_simPages = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_pgAC = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer3;
bSizer3 = new wxBoxSizer( wxVERTICAL );
bSizer3->Add( 0, 0, 1, wxEXPAND, 5 );
wxString m_acScaleChoices[] = { wxT("Decade"), wxT("Octave"), wxT("Linear") };
int m_acScaleNChoices = sizeof( m_acScaleChoices ) / sizeof( wxString );
m_acScale = new wxRadioBox( m_pgAC, wxID_ANY, wxT("Frequency scale"), wxDefaultPosition, wxDefaultSize, m_acScaleNChoices, m_acScaleChoices, 1, wxRA_SPECIFY_COLS );
m_acScale->SetSelection( 0 );
bSizer3->Add( m_acScale, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
bSizer3->Add( 0, 0, 1, wxEXPAND, 5 );
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText1 = new wxStaticText( m_pgAC, wxID_ANY, wxT("Number of points"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText1->Wrap( -1 );
fgSizer1->Add( m_staticText1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_acPointsNumber = new wxTextCtrl( m_pgAC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_acPointsNumber, 0, wxALL|wxEXPAND, 5 );
m_staticText2 = new wxStaticText( m_pgAC, wxID_ANY, wxT("Start frequency [Hz]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText2->Wrap( -1 );
fgSizer1->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_acFreqStart = new wxTextCtrl( m_pgAC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_acFreqStart, 0, wxALL|wxEXPAND, 5 );
m_staticText3 = new wxStaticText( m_pgAC, wxID_ANY, wxT("Stop frequency [Hz]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText3->Wrap( -1 );
fgSizer1->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_acFreqStop = new wxTextCtrl( m_pgAC, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_acFreqStop, 0, wxALL, 5 );
bSizer3->Add( fgSizer1, 1, wxALIGN_CENTER_HORIZONTAL, 5 );
bSizer3->Add( 0, 0, 1, wxEXPAND, 5 );
m_pgAC->SetSizer( bSizer3 );
m_pgAC->Layout();
bSizer3->Fit( m_pgAC );
m_simPages->AddPage( m_pgAC, wxT("AC"), true );
m_pgDC = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer4;
bSizer4 = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbSizer21;
sbSizer21 = new wxStaticBoxSizer( new wxStaticBox( m_pgDC, wxID_ANY, wxT("DC sweep source 1") ), wxVERTICAL );
m_dcEnable1 = new wxCheckBox( sbSizer21->GetStaticBox(), wxID_ANY, wxT("Enable"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizer21->Add( m_dcEnable1, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
wxFlexGridSizer* fgSizer21;
fgSizer21 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer21->SetFlexibleDirection( wxBOTH );
fgSizer21->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText41 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, wxT("DC source"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText41->Wrap( -1 );
fgSizer21->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_dcSource1 = new wxComboBox( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fgSizer21->Add( m_dcSource1, 0, wxALL, 5 );
m_staticText51 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, wxT("Starting voltage [V]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText51->Wrap( -1 );
fgSizer21->Add( m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_dcStart1 = new wxTextCtrl( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer21->Add( m_dcStart1, 0, wxALL, 5 );
m_staticText61 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, wxT("Final voltage [V]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText61->Wrap( -1 );
fgSizer21->Add( m_staticText61, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_dcStop1 = new wxTextCtrl( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer21->Add( m_dcStop1, 0, wxALL, 5 );
m_staticText71 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, wxT("Increment step [V]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText71->Wrap( -1 );
fgSizer21->Add( m_staticText71, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_dcIncr1 = new wxTextCtrl( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer21->Add( m_dcIncr1, 0, wxALL, 5 );
sbSizer21->Add( fgSizer21, 1, wxALIGN_CENTER_HORIZONTAL, 5 );
bSizer4->Add( sbSizer21, 1, wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer2;
sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( m_pgDC, wxID_ANY, wxT("DC sweep source 2") ), wxVERTICAL );
m_dcEnable2 = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, wxT("Enable"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizer2->Add( m_dcEnable2, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
wxFlexGridSizer* fgSizer2;
fgSizer2 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer2->SetFlexibleDirection( wxBOTH );
fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText4 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, wxT("DC source"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText4->Wrap( -1 );
fgSizer2->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_dcSource2 = new wxComboBox( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fgSizer2->Add( m_dcSource2, 0, wxALL, 5 );
m_staticText5 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, wxT("Starting voltage [V]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText5->Wrap( -1 );
fgSizer2->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_dcStart2 = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_dcStart2, 0, wxALL, 5 );
m_staticText6 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, wxT("Final voltage [V]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText6->Wrap( -1 );
fgSizer2->Add( m_staticText6, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_dcStop2 = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_dcStop2, 0, wxALL, 5 );
m_staticText7 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, wxT("Increment step [V]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText7->Wrap( -1 );
fgSizer2->Add( m_staticText7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_dcIncr2 = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_dcIncr2, 0, wxALL, 5 );
sbSizer2->Add( fgSizer2, 1, wxALIGN_CENTER_HORIZONTAL, 5 );
bSizer4->Add( sbSizer2, 1, wxEXPAND, 5 );
m_pgDC->SetSizer( bSizer4 );
m_pgDC->Layout();
bSizer4->Fit( m_pgDC );
m_simPages->AddPage( m_pgDC, wxT("DC Transfer"), false );
m_pgDistortion = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pgDistortion->Hide();
m_simPages->AddPage( m_pgDistortion, wxT("Distortion"), false );
m_pgNoise = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer15;
bSizer15 = new wxBoxSizer( wxVERTICAL );
bSizer15->Add( 0, 0, 1, wxEXPAND, 5 );
wxFlexGridSizer* fgSizer7;
fgSizer7 = new wxFlexGridSizer( 0, 3, 0, 0 );
fgSizer7->SetFlexibleDirection( wxBOTH );
fgSizer7->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText14 = new wxStaticText( m_pgNoise, wxID_ANY, wxT("Measured node"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText14->Wrap( -1 );
fgSizer7->Add( m_staticText14, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_noiseMeas = new wxComboBox( m_pgNoise, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fgSizer7->Add( m_noiseMeas, 0, wxALL, 5 );
fgSizer7->Add( 0, 0, 1, wxEXPAND, 5 );
m_staticText15 = new wxStaticText( m_pgNoise, wxID_ANY, wxT("Reference node"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText15->Wrap( -1 );
fgSizer7->Add( m_staticText15, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_noiseRef = new wxComboBox( m_pgNoise, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fgSizer7->Add( m_noiseRef, 0, wxALL, 5 );
m_staticText23 = new wxStaticText( m_pgNoise, wxID_ANY, wxT("(optional; default GND)"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText23->Wrap( -1 );
fgSizer7->Add( m_staticText23, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_staticText16 = new wxStaticText( m_pgNoise, wxID_ANY, wxT("Noise source"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText16->Wrap( -1 );
fgSizer7->Add( m_staticText16, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_noiseSrc = new wxComboBox( m_pgNoise, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fgSizer7->Add( m_noiseSrc, 0, wxALL, 5 );
fgSizer7->Add( 0, 0, 1, wxEXPAND, 5 );
bSizer15->Add( fgSizer7, 1, wxALIGN_CENTER_HORIZONTAL, 5 );
bSizer15->Add( 0, 0, 1, wxEXPAND, 5 );
wxString m_noiseScaleChoices[] = { wxT("Decade"), wxT("Octave"), wxT("Linear") };
int m_noiseScaleNChoices = sizeof( m_noiseScaleChoices ) / sizeof( wxString );
m_noiseScale = new wxRadioBox( m_pgNoise, wxID_ANY, wxT("Frequency scale"), wxDefaultPosition, wxDefaultSize, m_noiseScaleNChoices, m_noiseScaleChoices, 1, wxRA_SPECIFY_COLS );
m_noiseScale->SetSelection( 0 );
bSizer15->Add( m_noiseScale, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
bSizer15->Add( 0, 0, 1, wxEXPAND, 5 );
wxFlexGridSizer* fgSizer11;
fgSizer11 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer11->SetFlexibleDirection( wxBOTH );
fgSizer11->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText11 = new wxStaticText( m_pgNoise, wxID_ANY, wxT("Number of points"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText11->Wrap( -1 );
fgSizer11->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_noisePointsNumber = new wxTextCtrl( m_pgNoise, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer11->Add( m_noisePointsNumber, 0, wxALL, 5 );
m_staticText21 = new wxStaticText( m_pgNoise, wxID_ANY, wxT("Start frequency [Hz]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText21->Wrap( -1 );
fgSizer11->Add( m_staticText21, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_noiseFreqStart = new wxTextCtrl( m_pgNoise, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer11->Add( m_noiseFreqStart, 0, wxALL, 5 );
m_staticText31 = new wxStaticText( m_pgNoise, wxID_ANY, wxT("Stop frequency [Hz]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText31->Wrap( -1 );
fgSizer11->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_noiseFreqStop = new wxTextCtrl( m_pgNoise, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer11->Add( m_noiseFreqStop, 0, wxALL, 5 );
bSizer15->Add( fgSizer11, 1, wxALIGN_CENTER_HORIZONTAL, 5 );
bSizer15->Add( 0, 0, 1, wxEXPAND, 5 );
m_pgNoise->SetSizer( bSizer15 );
m_pgNoise->Layout();
bSizer15->Fit( m_pgNoise );
m_simPages->AddPage( m_pgNoise, wxT("Noise"), false );
m_pgOP = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer8;
bSizer8 = new wxBoxSizer( wxVERTICAL );
bSizer8->Add( 0, 0, 1, wxEXPAND, 5 );
m_staticText13 = new wxStaticText( m_pgOP, wxID_ANY, wxT("This tab has no settings"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText13->Wrap( -1 );
bSizer8->Add( m_staticText13, 0, wxALIGN_CENTER, 5 );
bSizer8->Add( 0, 0, 1, wxEXPAND, 5 );
m_pgOP->SetSizer( bSizer8 );
m_pgOP->Layout();
bSizer8->Fit( m_pgOP );
m_simPages->AddPage( m_pgOP, wxT("Operating Point"), false );
m_pgPoleZero = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pgPoleZero->Hide();
m_simPages->AddPage( m_pgPoleZero, wxT("Pole-Zero"), false );
m_pgSensitivity = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pgSensitivity->Hide();
m_simPages->AddPage( m_pgSensitivity, wxT("Sensitvity"), false );
m_pgTransferFunction = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pgTransferFunction->Hide();
m_simPages->AddPage( m_pgTransferFunction, wxT("Transfer Function"), false );
m_pgTransient = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer81;
bSizer81 = new wxBoxSizer( wxVERTICAL );
bSizer81->Add( 0, 0, 1, wxEXPAND, 5 );
wxFlexGridSizer* fgSizer6;
fgSizer6 = new wxFlexGridSizer( 0, 3, 0, 0 );
fgSizer6->SetFlexibleDirection( wxBOTH );
fgSizer6->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText151 = new wxStaticText( m_pgTransient, wxID_ANY, wxT("Time step [s]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText151->Wrap( -1 );
fgSizer6->Add( m_staticText151, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_transStep = new wxTextCtrl( m_pgTransient, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer6->Add( m_transStep, 0, wxALL, 5 );
fgSizer6->Add( 0, 0, 1, wxEXPAND, 5 );
m_staticText161 = new wxStaticText( m_pgTransient, wxID_ANY, wxT("Final time [s]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText161->Wrap( -1 );
fgSizer6->Add( m_staticText161, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_transFinal = new wxTextCtrl( m_pgTransient, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer6->Add( m_transFinal, 0, wxALL, 5 );
fgSizer6->Add( 0, 0, 1, wxEXPAND, 5 );
m_staticText17 = new wxStaticText( m_pgTransient, wxID_ANY, wxT("Initial time [s]"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText17->Wrap( -1 );
fgSizer6->Add( m_staticText17, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_transInitial = new wxTextCtrl( m_pgTransient, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer6->Add( m_transInitial, 0, wxALL, 5 );
m_staticText24 = new wxStaticText( m_pgTransient, wxID_ANY, wxT("(optional; default 0)"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText24->Wrap( -1 );
fgSizer6->Add( m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
bSizer81->Add( fgSizer6, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
bSizer81->Add( 0, 0, 1, wxEXPAND, 5 );
m_pgTransient->SetSizer( bSizer81 );
m_pgTransient->Layout();
bSizer81->Fit( m_pgTransient );
m_simPages->AddPage( m_pgTransient, wxT("Transient"), false );
m_pgCustom = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer2;
bSizer2 = new wxBoxSizer( wxVERTICAL );
m_staticText18 = new wxStaticText( m_pgCustom, wxID_ANY, wxT("Spice directives:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText18->Wrap( -1 );
bSizer2->Add( m_staticText18, 0, wxALL, 5 );
m_customTxt = new wxTextCtrl( m_pgCustom, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
m_customTxt->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
bSizer2->Add( m_customTxt, 1, wxALL|wxEXPAND, 5 );
m_loadDirectives = new wxButton( m_pgCustom, wxID_ANY, wxT("Load directives from schematic"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer2->Add( m_loadDirectives, 0, wxALL|wxEXPAND, 5 );
m_pgCustom->SetSizer( bSizer2 );
m_pgCustom->Layout();
bSizer2->Fit( m_pgCustom );
m_simPages->AddPage( m_pgCustom, wxT("Custom"), false );
bSizer1->Add( m_simPages, 1, wxEXPAND | wxALL, 5 );
m_sdbSizer1 = new wxStdDialogButtonSizer();
m_sdbSizer1OK = new wxButton( this, wxID_OK );
m_sdbSizer1->AddButton( m_sdbSizer1OK );
m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
m_sdbSizer1->Realize();
bSizer1->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizer1 );
this->Layout();
this->Centre( wxBOTH );
// Connect Events
m_loadDirectives->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onLoadDirectives ), NULL, this );
}
DIALOG_SIM_SETTINGS_BASE::~DIALOG_SIM_SETTINGS_BASE()
{
// Disconnect Events
m_loadDirectives->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_SETTINGS_BASE::onLoadDirectives ), NULL, this );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,121 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 24 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_SIM_SETTINGS_BASE_H__
#define __DIALOG_SIM_SETTINGS_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/string.h>
#include <wx/radiobox.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/valtext.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/checkbox.h>
#include <wx/combobox.h>
#include <wx/statbox.h>
#include <wx/button.h>
#include <wx/notebook.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_SIM_SETTINGS_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_SIM_SETTINGS_BASE : public wxDialog
{
private:
protected:
wxNotebook* m_simPages;
wxPanel* m_pgAC;
wxRadioBox* m_acScale;
wxStaticText* m_staticText1;
wxTextCtrl* m_acPointsNumber;
wxStaticText* m_staticText2;
wxTextCtrl* m_acFreqStart;
wxStaticText* m_staticText3;
wxTextCtrl* m_acFreqStop;
wxPanel* m_pgDC;
wxCheckBox* m_dcEnable1;
wxStaticText* m_staticText41;
wxComboBox* m_dcSource1;
wxStaticText* m_staticText51;
wxTextCtrl* m_dcStart1;
wxStaticText* m_staticText61;
wxTextCtrl* m_dcStop1;
wxStaticText* m_staticText71;
wxTextCtrl* m_dcIncr1;
wxCheckBox* m_dcEnable2;
wxStaticText* m_staticText4;
wxComboBox* m_dcSource2;
wxStaticText* m_staticText5;
wxTextCtrl* m_dcStart2;
wxStaticText* m_staticText6;
wxTextCtrl* m_dcStop2;
wxStaticText* m_staticText7;
wxTextCtrl* m_dcIncr2;
wxPanel* m_pgDistortion;
wxPanel* m_pgNoise;
wxStaticText* m_staticText14;
wxComboBox* m_noiseMeas;
wxStaticText* m_staticText15;
wxComboBox* m_noiseRef;
wxStaticText* m_staticText23;
wxStaticText* m_staticText16;
wxComboBox* m_noiseSrc;
wxRadioBox* m_noiseScale;
wxStaticText* m_staticText11;
wxTextCtrl* m_noisePointsNumber;
wxStaticText* m_staticText21;
wxTextCtrl* m_noiseFreqStart;
wxStaticText* m_staticText31;
wxTextCtrl* m_noiseFreqStop;
wxPanel* m_pgOP;
wxStaticText* m_staticText13;
wxPanel* m_pgPoleZero;
wxPanel* m_pgSensitivity;
wxPanel* m_pgTransferFunction;
wxPanel* m_pgTransient;
wxStaticText* m_staticText151;
wxTextCtrl* m_transStep;
wxStaticText* m_staticText161;
wxTextCtrl* m_transFinal;
wxStaticText* m_staticText17;
wxTextCtrl* m_transInitial;
wxStaticText* m_staticText24;
wxPanel* m_pgCustom;
wxStaticText* m_staticText18;
wxTextCtrl* m_customTxt;
wxButton* m_loadDirectives;
wxStdDialogButtonSizer* m_sdbSizer1;
wxButton* m_sdbSizer1OK;
wxButton* m_sdbSizer1Cancel;
// Virtual event handlers, overide them in your derived class
virtual void onLoadDirectives( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_SIM_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Simulation settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 439,534 ), long style = wxDEFAULT_DIALOG_STYLE );
~DIALOG_SIM_SETTINGS_BASE();
};
#endif //__DIALOG_SIM_SETTINGS_BASE_H__

View File

@ -47,11 +47,12 @@ bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsign
}
bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* formatter, int aCtl )
bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* aFormatter, int aCtl )
{
std::vector<int> pinSequence; // numeric indices into m_SortedComponentPinList
wxArrayString stdPinNameArray; // Array containing Standard Pin Names
const wxString delimiters( "{:,; }" );
SCH_SHEET_LIST sheetList( g_RootSheet );
// Netlist options
bool useNetcodeAsNetName = aCtl & NET_USE_NETCODES_AS_NETNAMES;
@ -60,52 +61,14 @@ bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* formatter, int aCtl )
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
m_masterList->GetItem( ii )->m_Flag = 0;
SCH_SHEET_LIST sheetList( g_RootSheet );
std::vector<wxString> directives;
formatter->Print( 0, ".title KiCad schematic\n" );
aFormatter->Print( 0, ".title KiCad schematic\n" );
m_netMap.clear();
// Ground net has to be always assigned to node 0
m_netMap["GND"] = 0;
for( unsigned i = 0; i < sheetList.size(); i++ )
{
for( EDA_ITEM* item = sheetList[i].LastDrawList(); item; item = item->Next() )
{
if( item->Type() != SCH_TEXT_T )
continue;
wxString text = static_cast<SCH_TEXT*>( item )->GetText();
if( text.IsEmpty() )
continue;
if( text.GetChar( 0 ) == '.' )
{
wxStringTokenizer tokenizer( text, "\r\n" );
while( tokenizer.HasMoreTokens() )
{
wxString directive( tokenizer.GetNextToken() );
// Fix paths for .include directives
if( aCtl & NET_ADJUST_INCLUDE_PATHS && m_paths && directive.StartsWith( ".inc" ) )
{
wxString file( directive.AfterFirst( ' ' ) );
wxString path( m_paths->FindValidPath( file ) );
directives.push_back( wxString( ".include " ) + path );
}
else
{
directives.push_back( directive );
}
}
}
}
}
UpdateDirectives( aCtl );
m_ReferencesAlreadyFound.Clear();
int curNetIndex = 1;
@ -192,7 +155,7 @@ bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* formatter, int aCtl )
int activePinIndex = 0;
formatter->Print( 0, "%s%s ", (const char*) primType.c_str(), (const char*) RefName.c_str() );
aFormatter->Print( 0, "%s%s ", (const char*) primType.c_str(), (const char*) RefName.c_str() );
for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
{
@ -244,7 +207,7 @@ bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* formatter, int aCtl )
if( useNetcodeAsNetName )
{
formatter->Print( 0, "%d ", netIdx );
aFormatter->Print( 0, "%d ", netIdx );
}
else
{
@ -257,21 +220,18 @@ bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* formatter, int aCtl )
if( netName.IsEmpty() )
netName = wxT( "?" );
formatter->Print( 0, "%s ", TO_UTF8( netName ) );
aFormatter->Print( 0, "%s ", TO_UTF8( netName ) );
}
}
formatter->Print( 0, "%s\n", (const char*) model.c_str() );
aFormatter->Print( 0, "%s\n", (const char*) model.c_str() );
}
}
// Print out all directives found in the text fields on the schematics
for( auto& dir : directives )
{
formatter->Print( 0, "%s\n", (const char*) dir.c_str() );
}
writeDirectives( aFormatter, aCtl );
formatter->Print( -1, ".end\n" );
aFormatter->Print( -1, ".end\n" );
return true;
}
@ -349,6 +309,60 @@ wxString NETLIST_EXPORTER_PSPICE::GetSpiceFieldDefVal( const wxString& aField,
return wxString( "<unknown>" );
}
void NETLIST_EXPORTER_PSPICE::UpdateDirectives( int aCtl )
{
const SCH_SHEET_LIST& sheetList = g_RootSheet;
m_directives.clear();
for( unsigned i = 0; i < sheetList.size(); i++ )
{
for( EDA_ITEM* item = sheetList[i].LastDrawList(); item; item = item->Next() )
{
if( item->Type() != SCH_TEXT_T )
continue;
wxString text = static_cast<SCH_TEXT*>( item )->GetText();
if( text.IsEmpty() )
continue;
if( text.GetChar( 0 ) == '.' )
{
wxStringTokenizer tokenizer( text, "\r\n" );
while( tokenizer.HasMoreTokens() )
{
wxString directive( tokenizer.GetNextToken() );
// Fix paths for .include directives
if( aCtl & NET_ADJUST_INCLUDE_PATHS && m_paths && directive.StartsWith( ".inc" ) )
{
wxString file( directive.AfterFirst( ' ' ) );
wxString path( m_paths->FindValidPath( file ) );
m_directives.push_back( wxString( ".include " ) + path );
}
else
{
m_directives.push_back( directive );
}
}
}
}
}
}
void NETLIST_EXPORTER_PSPICE::writeDirectives( OUTPUTFORMATTER* aFormatter, int aCtl ) const
{
for( auto& dir : m_directives )
{
aFormatter->Print( 0, "%s\n", (const char*) dir.c_str() );
}
}
const std::vector<wxString> NETLIST_EXPORTER_PSPICE::m_spiceFields = {
"Spice_Primitive",
"Spice_Model",

View File

@ -48,11 +48,16 @@ enum SPICE_NETLIST_OPTIONS {
class NETLIST_EXPORTER_PSPICE : public NETLIST_EXPORTER
{
public:
NETLIST_EXPORTER_PSPICE( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs, SEARCH_STACK* aPaths = NULL ) :
NETLIST_EXPORTER_PSPICE( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs,
SEARCH_STACK* aPaths = NULL ) :
NETLIST_EXPORTER( aMasterList, aLibs ), m_paths( aPaths )
{
}
virtual ~NETLIST_EXPORTER_PSPICE()
{
}
///> Net name to node number mapping
typedef std::map<wxString, int> NET_INDEX_MAP;
@ -62,7 +67,7 @@ public:
*/
bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions );
bool Format( OUTPUTFORMATTER* aOutputFormatter, int aCtl );
bool Format( OUTPUTFORMATTER* aFormatter, int aCtl );
const NET_INDEX_MAP& GetNetIndexMap() const
{
@ -76,11 +81,25 @@ public:
static wxString GetSpiceFieldDefVal( const wxString& aField, SCH_COMPONENT* aComponent, int aCtl );
void UpdateDirectives( int aCtl );
const std::vector<wxString> GetDirectives() const
{
return m_directives;
}
protected:
virtual void writeDirectives( OUTPUTFORMATTER* aFormatter, int aCtl ) const;
private:
// Spice directives found in the processed schematic sheet
std::vector<wxString> m_directives;
NET_INDEX_MAP m_netMap;
SEARCH_STACK* m_paths;
// Fields that are used during netlist export & simulation
// Component fields that are processed during netlist export & simulation
static const std::vector<wxString> m_spiceFields;
};

View File

@ -74,14 +74,78 @@ private:
};
/// Special netlist exporter flavor that allows to override simulation commands
class NETLIST_EXPORTER_PSPICE_SIM : public NETLIST_EXPORTER_PSPICE
{
public:
NETLIST_EXPORTER_PSPICE_SIM( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs,
SEARCH_STACK* aPaths = NULL ) :
NETLIST_EXPORTER_PSPICE( aMasterList, aLibs, aPaths )
{
}
void SetSimCommand( const wxString& aCmd )
{
m_simCommand = aCmd;
}
const wxString& GetSimCommand() const
{
return m_simCommand;
}
void ClearSimCommand()
{
m_simCommand.Clear();
}
protected:
virtual void writeDirectives( OUTPUTFORMATTER* aFormatter, int aCtl ) const
{
if( m_simCommand.IsEmpty() )
{
// Fallback to the default behavior
NETLIST_EXPORTER_PSPICE::writeDirectives( aFormatter, aCtl );
}
// Dump all directives, but simulation commands
for( const auto& dir : GetDirectives() )
{
if( !isSimCommand( dir ) )
aFormatter->Print( 0, "%s\n", (const char*) dir.c_str() );
}
// Finish with our custom simulation command
aFormatter->Print( 0, "%s\n", (const char*) m_simCommand.c_str() );
}
private:
bool isSimCommand( const wxString& aCmd ) const
{
const std::vector<wxString> simCmds = {
".ac", ".dc", ".disto", ".noise", ".op", ".pz", ".sens", ".tf", ".tran", ".pss"
};
wxString lcaseCmd = aCmd.Lower();
for( const auto& c : simCmds )
{
if( lcaseCmd.StartsWith( c ) )
return true;
}
return false;
}
wxString m_simCommand;
};
SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
: SIM_PLOT_FRAME_BASE( aParent )
: SIM_PLOT_FRAME_BASE( aParent ), m_settingsDlg( this )
{
SetKiway( this, aKiway );
m_exporter = NULL;
m_simulator = NULL;
Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SIM_PLOT_FRAME::onClose ), NULL, this );
Connect( EVT_SIM_REPORT, wxCommandEventHandler( SIM_PLOT_FRAME::onSimReport ), NULL, this );
Connect( EVT_SIM_STARTED, wxCommandEventHandler( SIM_PLOT_FRAME::onSimStarted ), NULL, this );
@ -94,28 +158,28 @@ SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
SIM_PLOT_FRAME::~SIM_PLOT_FRAME()
{
delete m_exporter;
delete m_simulator;
}
void SIM_PLOT_FRAME::StartSimulation()
{
delete m_exporter;
delete m_simulator;
m_simConsole->Clear();
// TODO check if there is a valid simulation command
/// @todo is it necessary to recreate simulator every time?
m_simulator = SPICE_SIMULATOR::CreateInstance( "ngspice" );
m_simulator.reset( SPICE_SIMULATOR::CreateInstance( "ngspice" ) );
m_simulator->SetReporter( new SIM_THREAD_REPORTER( this ) );
m_simulator->Init();
NETLIST_OBJECT_LIST* net_atoms = m_schematicFrame->BuildNetListBase();
STRING_FORMATTER formatter;
m_exporter = new NETLIST_EXPORTER_PSPICE( net_atoms, Prj().SchLibs(), Prj().SchSearchS() );
m_exporter.reset( new NETLIST_EXPORTER_PSPICE_SIM( net_atoms,
Prj().SchLibs(), Prj().SchSearchS() ) );
m_exporter->SetSimCommand( m_simCommand );
m_exporter->Format( &formatter, GNL_ALL );
m_simulator->LoadNetlist( formatter.GetString() );
m_simulator->Run();
}
@ -349,6 +413,17 @@ void SIM_PLOT_FRAME::onSimulate( wxCommandEvent& event )
}
void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
{
// TODO set exporter
if( m_settingsDlg.ShowModal() == wxID_OK )
m_simCommand = m_settingsDlg.GetSimCommand();
wxLogDebug( "sim command = %s", m_simCommand ); // TODO remove
}
void SIM_PLOT_FRAME::onPlaceProbe( wxCommandEvent& event )
{
if( m_schematicFrame == NULL )

View File

@ -32,11 +32,12 @@
#include "sim_plot_frame_base.h"
#include "kiway_player.h"
#include <netlist_exporters/netlist_exporter_pspice.h>
#include <dialogs/dialog_sim_settings.h>
#include <wx/event.h>
class SPICE_SIMULATOR;
class NETLIST_EXPORTER_PSPICE;
class NETLIST_EXPORTER_PSPICE_SIM;
class SIM_PLOT_PANEL;
/** Implementing SIM_PLOT_FRAME_BASE */
@ -110,6 +111,7 @@ class SIM_PLOT_FRAME : public SIM_PLOT_FRAME_BASE
void onSignalRClick( wxMouseEvent& event ) override;
void onSimulate( wxCommandEvent& event ) override;
void onSettings( wxCommandEvent& event ) override;
void onPlaceProbe( wxCommandEvent& event ) override;
void onClose( wxCloseEvent& aEvent );
@ -120,8 +122,12 @@ class SIM_PLOT_FRAME : public SIM_PLOT_FRAME_BASE
void onSimReport( wxCommandEvent& aEvent );
SCH_EDIT_FRAME* m_schematicFrame;
NETLIST_EXPORTER_PSPICE* m_exporter;
SPICE_SIMULATOR* m_simulator;
std::unique_ptr<NETLIST_EXPORTER_PSPICE_SIM> m_exporter;
std::unique_ptr<SPICE_SIMULATOR> m_simulator;
wxString m_simCommand;
// Trick to preserve settings between runs
DIALOG_SIM_SETTINGS m_settingsDlg;
// Right click context menu for signals in the listbox
class SIGNAL_CONTEXT_MENU : public wxMenu

View File

@ -107,22 +107,23 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const
m_cursors = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL );
bSizer7->Add( m_cursors, 1, wxALL|wxEXPAND, 5 );
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 1, 0, 0, 0 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxBoxSizer* bSizer4;
bSizer4 = new wxBoxSizer( wxHORIZONTAL );
m_simulateBtn = new wxButton( this, wxID_ANY, _("Simulate"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_simulateBtn, 0, wxALL, 5 );
bSizer4->Add( m_simulateBtn, 1, wxALL, 5 );
m_settingsBtn = new wxButton( this, wxID_ANY, _("Settings"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer4->Add( m_settingsBtn, 1, wxALL, 5 );
m_probeBtn = new wxButton( this, wxID_ANY, _("Probe"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_probeBtn, 0, wxALL|wxEXPAND, 5 );
bSizer4->Add( m_probeBtn, 1, wxALL, 5 );
m_tuneBtn = new wxButton( this, wxID_ANY, _("Tune"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_tuneBtn, 0, wxALL|wxEXPAND, 5 );
bSizer4->Add( m_tuneBtn, 1, wxALL, 5 );
bSizer7->Add( fgSizer1, 0, wxALL|wxEXPAND, 5 );
bSizer7->Add( bSizer4, 0, 0, 5 );
bSizer5->Add( bSizer7, 1, wxEXPAND, 5 );
@ -161,6 +162,7 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const
m_signals->Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onSignalDblClick ), NULL, this );
m_signals->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( SIM_PLOT_FRAME_BASE::onSignalRClick ), NULL, this );
m_simulateBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onSimulate ), NULL, this );
m_settingsBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onSettings ), NULL, this );
m_probeBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onPlaceProbe ), NULL, this );
m_tuneBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onTune ), NULL, this );
}
@ -187,6 +189,7 @@ SIM_PLOT_FRAME_BASE::~SIM_PLOT_FRAME_BASE()
m_signals->Disconnect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onSignalDblClick ), NULL, this );
m_signals->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( SIM_PLOT_FRAME_BASE::onSignalRClick ), NULL, this );
m_simulateBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onSimulate ), NULL, this );
m_settingsBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onSettings ), NULL, this );
m_probeBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onPlaceProbe ), NULL, this );
m_tuneBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::onTune ), NULL, this );

View File

@ -88,7 +88,7 @@
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxMenuBar" expanded="1">
<object class="wxMenuBar" expanded="0">
<property name="bg"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
@ -133,7 +133,7 @@
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxMenu" expanded="1">
<object class="wxMenu" expanded="0">
<property name="label">File</property>
<property name="name">m_fileMenu</property>
<property name="permission">protected</property>
@ -190,7 +190,7 @@
<property name="name">m_separator1</property>
<property name="permission">none</property>
</object>
<object class="wxMenuItem" expanded="1">
<object class="wxMenuItem" expanded="0">
<property name="bitmap"></property>
<property name="checked">0</property>
<property name="enabled">1</property>
@ -205,7 +205,7 @@
<event name="OnMenuSelection">menuSaveImage</event>
<event name="OnUpdateUI"></event>
</object>
<object class="wxMenuItem" expanded="1">
<object class="wxMenuItem" expanded="0">
<property name="bitmap"></property>
<property name="checked">0</property>
<property name="enabled">1</property>
@ -220,7 +220,7 @@
<event name="OnMenuSelection">menuSaveCsv</event>
<event name="OnUpdateUI"></event>
</object>
<object class="separator" expanded="1">
<object class="separator" expanded="0">
<property name="name">m_separator4</property>
<property name="permission">none</property>
</object>
@ -240,7 +240,7 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="wxMenu" expanded="1">
<object class="wxMenu" expanded="0">
<property name="label">View</property>
<property name="name">m_viewMenu</property>
<property name="permission">protected</property>
@ -438,11 +438,11 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="0">
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizer7</property>
<property name="orient">wxVERTICAL</property>
@ -806,26 +806,19 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="flag"></property>
<property name="proportion">0</property>
<object class="wxFlexGridSizer" expanded="0">
<property name="cols">0</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols"></property>
<property name="growablerows"></property>
<property name="hgap">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">fgSizer1</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="name">bSizer4</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<property name="rows">1</property>
<property name="vgap">0</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
@ -910,10 +903,98 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Settings</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_settingsBtn</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onSettings</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<property name="flag">wxALL</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
@ -1000,8 +1081,8 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<property name="flag">wxALL</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>

View File

@ -52,6 +52,7 @@ class SIM_PLOT_FRAME_BASE : public KIWAY_PLAYER
wxStaticText* m_staticText21;
wxListCtrl* m_cursors;
wxButton* m_simulateBtn;
wxButton* m_settingsBtn;
wxButton* m_probeBtn;
wxButton* m_tuneBtn;
wxRichTextCtrl* m_simConsole;
@ -76,6 +77,7 @@ class SIM_PLOT_FRAME_BASE : public KIWAY_PLAYER
virtual void onSignalDblClick( wxCommandEvent& event ) { event.Skip(); }
virtual void onSignalRClick( wxMouseEvent& event ) { event.Skip(); }
virtual void onSimulate( wxCommandEvent& event ) { event.Skip(); }
virtual void onSettings( wxCommandEvent& event ) { event.Skip(); }
virtual void onPlaceProbe( wxCommandEvent& event ) { event.Skip(); }
virtual void onTune( wxCommandEvent& event ) { event.Skip(); }

View File

@ -99,9 +99,6 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( wxWindow* parent, wxWindowID id, const wxPoint&
const wxSize& size, long style, const wxString& name )
: mpWindow( parent, id, pos, size, style ), m_colorIdx( 0 )
{
//SetMargins( 10, 10, 10, 10 );
LockAspect();
m_axis_x = new mpScaleX( wxT( "T [s]" ) );
m_axis_x->SetTicks( false );
AddLayer( m_axis_x );