Eeschema: adding .op SPICE simulation support
ADDED new tab on simulation settings dialog, which allows to run .op analysis. Fixes https://gitlab.com/kicad/code/kicad/-/issues/2368
This commit is contained in:
parent
6a8ace55c4
commit
fdccdd5cb9
|
@ -272,6 +272,7 @@ if( KICAD_SPICE )
|
|||
sim/sim_plot_frame.cpp
|
||||
sim/sim_plot_frame_base.cpp
|
||||
sim/sim_plot_panel.cpp
|
||||
sim/sim_panel_base.cpp
|
||||
sim/spice_simulator.cpp
|
||||
sim/spice_value.cpp
|
||||
simulation_cursors.cpp
|
||||
|
|
|
@ -67,7 +67,6 @@ DIALOG_SIM_SETTINGS::DIALOG_SIM_SETTINGS( wxWindow* aParent )
|
|||
// wxPanel::Hide() isn't enough on some platforms
|
||||
m_simPages->RemovePage( m_simPages->FindPage( m_pgDistortion ) );
|
||||
m_simPages->RemovePage( m_simPages->FindPage( m_pgNoise ) );
|
||||
m_simPages->RemovePage( m_simPages->FindPage( m_pgOP ) );
|
||||
m_simPages->RemovePage( m_simPages->FindPage( m_pgPoleZero ) );
|
||||
m_simPages->RemovePage( m_simPages->FindPage( m_pgSensitivity ) );
|
||||
m_simPages->RemovePage( m_simPages->FindPage( m_pgTransferFunction ) );
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Dec 30 2017)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -317,8 +317,6 @@ DIALOG_SIM_SETTINGS_BASE::DIALOG_SIM_SETTINGS_BASE( wxWindow* parent, wxWindowID
|
|||
bSizer15->Fit( m_pgNoise );
|
||||
m_simPages->AddPage( m_pgNoise, _("Noise"), false );
|
||||
m_pgOP = new wxPanel( m_simPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
m_pgOP->Hide();
|
||||
|
||||
wxBoxSizer* bSizer8;
|
||||
bSizer8 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,11 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Dec 30 2017)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __DIALOG_SIM_SETTINGS_BASE_H__
|
||||
#define __DIALOG_SIM_SETTINGS_BASE_H__
|
||||
#pragma once
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
@ -134,4 +133,3 @@ class DIALOG_SIM_SETTINGS_BASE : public DIALOG_SHIM
|
|||
|
||||
};
|
||||
|
||||
#endif //__DIALOG_SIM_SETTINGS_BASE_H__
|
||||
|
|
|
@ -443,9 +443,7 @@ void NETLIST_EXPORTER_PSPICE::UpdateDirectives( unsigned aCtl )
|
|||
|| couplingK.Matches( line ) // K## L## L## coupling constant
|
||||
|| ( directiveStarted && line.StartsWith( '+' ) ) ) // multiline directives
|
||||
{
|
||||
// Pad the directive to ensure we distinguish between short directives
|
||||
// and the start of a longer directive
|
||||
m_directives.emplace_back( line + " " );
|
||||
m_directives.push_back( line );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,10 +23,11 @@
|
|||
*/
|
||||
|
||||
#include "netlist_exporter_pspice_sim.h"
|
||||
#include <wx/regex.h>
|
||||
#include <wx/tokenzr.h>
|
||||
|
||||
wxString NETLIST_EXPORTER_PSPICE_SIM::GetSpiceVector( const wxString& aName, SIM_PLOT_TYPE aType,
|
||||
const wxString& aParam ) const
|
||||
wxString NETLIST_EXPORTER_PSPICE_SIM::ComponentToVector(
|
||||
const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam ) const
|
||||
{
|
||||
wxString res;
|
||||
|
||||
|
@ -68,6 +69,41 @@ wxString NETLIST_EXPORTER_PSPICE_SIM::GetSpiceVector( const wxString& aName, SIM
|
|||
}
|
||||
|
||||
|
||||
SIM_PLOT_TYPE NETLIST_EXPORTER_PSPICE_SIM::VectorToSignal(
|
||||
const std::string& aVector, wxString& aSignal ) const
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// See ngspice manual chapt. 31.1 "Accessing internal device parameters"
|
||||
wxRegEx internalDevParameter( "^@(\\w*[\\.\\w+]*)\\[(\\w*)\\]$", wxRE_ADVANCED );
|
||||
wxString vector( aVector );
|
||||
|
||||
if( !internalDevParameter.Matches( vector ) )
|
||||
{
|
||||
// any text is a node name, which returns voltage
|
||||
aSignal = "V(" + aVector + ")";
|
||||
return SPT_VOLTAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString paramType = internalDevParameter.GetMatch( vector, 2 );
|
||||
|
||||
if( paramType.Lower()[0] == 'i' )
|
||||
{
|
||||
// this is a branch current
|
||||
paramType[0] = 'I';
|
||||
aSignal = paramType + "(";
|
||||
aSignal += internalDevParameter.GetMatch( vector, 1 ).Upper() + ")";
|
||||
return SPT_CURRENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SPT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const std::vector<wxString>& NETLIST_EXPORTER_PSPICE_SIM::GetCurrents( SPICE_PRIMITIVE aPrimitive )
|
||||
{
|
||||
static const std::vector<wxString> passive = { "I" };
|
||||
|
@ -129,16 +165,23 @@ SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::GetSimType()
|
|||
|
||||
SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( const wxString& aCmd )
|
||||
{
|
||||
const std::map<wxString, SIM_TYPE> simCmds = {
|
||||
{ ".ac ", ST_AC }, { ".dc ", ST_DC }, { ".disto ", ST_DISTORTION }, { ".noise ", ST_NOISE },
|
||||
{ ".op ", ST_OP }, { ".pz ", ST_POLE_ZERO }, { ".sens ", ST_SENSITIVITY }, { ".tf ", ST_TRANS_FUNC },
|
||||
{ ".tran ", ST_TRANSIENT }
|
||||
};
|
||||
wxString lcaseCmd = aCmd.Lower();
|
||||
const std::vector<std::pair<wxString, SIM_TYPE>> simCmds = {
|
||||
{ "^.ac\\M.*", ST_AC },
|
||||
{ "^.dc\\M.*", ST_DC },
|
||||
{ "^.tran\\M.*", ST_TRANSIENT },
|
||||
{ "^.op\\M.*", ST_OP },
|
||||
{ "^.disto\\M.*", ST_DISTORTION },
|
||||
{ "^.noise\\M.*", ST_NOISE },
|
||||
{ "^.pz\\M.*", ST_POLE_ZERO },
|
||||
{ "^.sens\\M.*", ST_SENSITIVITY },
|
||||
{ "^.tf\\M.*", ST_TRANS_FUNC } };
|
||||
wxRegEx simCmd;
|
||||
|
||||
for( const auto& c : simCmds )
|
||||
{
|
||||
if( lcaseCmd.StartsWith( c.first ) )
|
||||
simCmd.Compile( c.first, wxRE_ADVANCED | wxRE_NOSUB | wxRE_ICASE );
|
||||
|
||||
if( simCmd.Matches( aCmd ) )
|
||||
return c.second;
|
||||
}
|
||||
|
||||
|
@ -193,7 +236,8 @@ void NETLIST_EXPORTER_PSPICE_SIM::writeDirectives( OUTPUTFORMATTER* aFormatter,
|
|||
|
||||
/// @todo is it required to switch to lowercase
|
||||
aFormatter->Print( 0, ".save %s\n",
|
||||
(const char*) GetSpiceVector( item.m_refName, SPT_CURRENT, current ).c_str() );
|
||||
(const char*) ComponentToVector( item.m_refName, SPT_CURRENT, current )
|
||||
.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,7 +246,7 @@ void NETLIST_EXPORTER_PSPICE_SIM::writeDirectives( OUTPUTFORMATTER* aFormatter,
|
|||
{
|
||||
// the "0" and the "GND" nets are automaticallly saved internally by ngspice.
|
||||
// Skip them
|
||||
wxString netname = GetSpiceVector( netMap.first, SPT_VOLTAGE );
|
||||
wxString netname = ComponentToVector( netMap.first, SPT_VOLTAGE );
|
||||
|
||||
if( netname == "V(0)" || netname == "V(GND)" )
|
||||
continue;
|
||||
|
|
|
@ -60,9 +60,18 @@ public:
|
|||
* @return Empty string if query is invalid, otherwise a plot name that
|
||||
* can be requested from the simulator.
|
||||
*/
|
||||
wxString GetSpiceVector( const wxString& aName, SIM_PLOT_TYPE aType,
|
||||
wxString ComponentToVector( const wxString& aName, SIM_PLOT_TYPE aType,
|
||||
const wxString& aParam = wxEmptyString ) const;
|
||||
|
||||
/**
|
||||
* @brief Returns name of Spice dataset for a specific plot.
|
||||
* @param aVector is name of the vector produced by ngspice
|
||||
* @param [out] aSignal is output in form: V(R1), Ib(Q2), I(L8)
|
||||
* @return [SPT_VOLTAGE, SPT_CURRENT]. Otherwise SPT_UNKNOWN if vector is
|
||||
* of different, unsupported type.
|
||||
*/
|
||||
SIM_PLOT_TYPE VectorToSignal( const std::string& aVector, wxString& aSignal ) const;
|
||||
|
||||
/**
|
||||
* @brief Returns a list of currents that can be probed in a Spice primitive.
|
||||
*/
|
||||
|
|
|
@ -41,15 +41,16 @@ using namespace std;
|
|||
|
||||
static const wxChar* const traceNgspice = wxT( "KICAD_NGSPICE" );
|
||||
|
||||
NGSPICE::NGSPICE() :
|
||||
m_ngSpice_Init( nullptr ),
|
||||
m_ngSpice_Circ( nullptr ),
|
||||
m_ngSpice_Command( nullptr ),
|
||||
m_ngGet_Vec_Info( nullptr ),
|
||||
m_ngSpice_AllPlots( nullptr ),
|
||||
m_ngSpice_AllVecs( nullptr ),
|
||||
m_ngSpice_Running( nullptr ),
|
||||
m_error( false )
|
||||
NGSPICE::NGSPICE()
|
||||
: m_ngSpice_Init( nullptr ),
|
||||
m_ngSpice_Circ( nullptr ),
|
||||
m_ngSpice_Command( nullptr ),
|
||||
m_ngGet_Vec_Info( nullptr ),
|
||||
m_ngSpice_CurPlot( nullptr ),
|
||||
m_ngSpice_AllPlots( nullptr ),
|
||||
m_ngSpice_AllVecs( nullptr ),
|
||||
m_ngSpice_Running( nullptr ),
|
||||
m_error( false )
|
||||
{
|
||||
init_dll();
|
||||
}
|
||||
|
@ -66,6 +67,28 @@ void NGSPICE::Init()
|
|||
}
|
||||
|
||||
|
||||
vector<string> NGSPICE::AllPlots()
|
||||
{
|
||||
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;
|
||||
|
||||
if( allPlots != nullptr )
|
||||
for( char** plot = allPlots; *plot != nullptr; plot++ )
|
||||
noOfPlots++;
|
||||
|
||||
vector<string> retVal( noOfPlots );
|
||||
for( int i = 0; i < noOfPlots; i++, allPlots++ )
|
||||
{
|
||||
string vec = *allPlots;
|
||||
retVal.at( i ) = vec;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
vector<COMPLEX> NGSPICE::GetPlot( const string& aName, int aMaxLen )
|
||||
{
|
||||
LOCALE_IO c_locale; // ngspice works correctly only with C locale
|
||||
|
@ -361,6 +384,7 @@ void NGSPICE::init_dll()
|
|||
m_ngSpice_Circ = (ngSpice_Circ) m_dll.GetSymbol( "ngSpice_Circ" );
|
||||
m_ngSpice_Command = (ngSpice_Command) m_dll.GetSymbol( "ngSpice_Command" );
|
||||
m_ngGet_Vec_Info = (ngGet_Vec_Info) m_dll.GetSymbol( "ngGet_Vec_Info" );
|
||||
m_ngSpice_CurPlot = (ngSpice_CurPlot) m_dll.GetSymbol( "ngSpice_CurPlot" );
|
||||
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" ); // it is not a typo
|
||||
|
|
|
@ -59,6 +59,9 @@ public:
|
|||
///> @copydoc SPICE_SIMULATOR::GetXAxis()
|
||||
std::string GetXAxis( SIM_TYPE aType ) const override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::AllPlots()
|
||||
std::vector<std::string> AllPlots() override;
|
||||
|
||||
///> @copydoc SPICE_SIMULATOR::GetPlot()
|
||||
std::vector<COMPLEX> GetPlot( const std::string& aName, int aMaxLen = -1 ) override;
|
||||
|
||||
|
@ -89,6 +92,7 @@ private:
|
|||
typedef int (*ngSpice_Circ)( char** circarray );
|
||||
typedef int (*ngSpice_Command)( char* command );
|
||||
typedef pvector_info (*ngGet_Vec_Info)( char* vecname );
|
||||
typedef char* ( *ngSpice_CurPlot )( void );
|
||||
typedef char** (*ngSpice_AllPlots)( void );
|
||||
typedef char** (*ngSpice_AllVecs)( char* plotname );
|
||||
typedef bool (*ngSpice_Running)( void );
|
||||
|
@ -98,6 +102,7 @@ private:
|
|||
ngSpice_Circ m_ngSpice_Circ;
|
||||
ngSpice_Command m_ngSpice_Command;
|
||||
ngGet_Vec_Info m_ngGet_Vec_Info;
|
||||
ngSpice_CurPlot m_ngSpice_CurPlot;
|
||||
ngSpice_AllPlots m_ngSpice_AllPlots;
|
||||
ngSpice_AllVecs m_ngSpice_AllVecs;
|
||||
ngSpice_Running m_ngSpice_Running;
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 CERN
|
||||
* @author Sylwester Kocjan <s.kocjan@o2.pl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "sim_panel_base.h"
|
||||
|
||||
#include "sim_plot_frame.h"
|
||||
|
||||
#include <wx/sizer.h>
|
||||
|
||||
|
||||
SIM_PANEL_BASE::SIM_PANEL_BASE() : m_type( ST_UNKNOWN )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SIM_PANEL_BASE::SIM_PANEL_BASE( SIM_TYPE aType ) : m_type( aType )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SIM_PANEL_BASE::SIM_PANEL_BASE( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size, long style, const wxString& name )
|
||||
: wxWindow( parent, id, pos, size, style, name ), m_type( aType )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SIM_PANEL_BASE::~SIM_PANEL_BASE()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool SIM_PANEL_BASE::IsPlottable( SIM_TYPE aSimType )
|
||||
{
|
||||
switch( aSimType )
|
||||
{
|
||||
case ST_AC:
|
||||
case ST_DC:
|
||||
case ST_TRANSIENT:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SIM_NOPLOT_PANEL::SIM_NOPLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size, long style, const wxString& name )
|
||||
: SIM_PANEL_BASE( aType, parent, id, pos, size, style, name )
|
||||
{
|
||||
m_sizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_sizer->Add( 0, 1, 1, wxEXPAND, 5 );
|
||||
|
||||
m_textInfo = new wxStaticText( dynamic_cast<wxWindow*>( this ), wxID_ANY, "", wxDefaultPosition,
|
||||
wxDefaultSize, wxALL | wxEXPAND | wxALIGN_CENTER_HORIZONTAL );
|
||||
m_textInfo->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT,
|
||||
wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
|
||||
m_textInfo->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
|
||||
|
||||
//ST_UNKNOWN serves purpose of a welcome panel
|
||||
m_textInfo->SetLabel(
|
||||
( aType == ST_UNKNOWN ) ?
|
||||
_( "Start the simulation by clicking the Run Simulation button" ) :
|
||||
_( "This simulation provide no plots. Please refer to console window for results" ) );
|
||||
|
||||
m_sizer->Add( m_textInfo, 1, wxALL | wxEXPAND, 5 );
|
||||
m_sizer->Add( 0, 1, 1, wxEXPAND, 5 );
|
||||
|
||||
dynamic_cast<wxWindow*>( this )->SetSizer( m_sizer );
|
||||
}
|
||||
|
||||
|
||||
SIM_NOPLOT_PANEL::~SIM_NOPLOT_PANEL()
|
||||
{
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 CERN
|
||||
* Copyright (C) 2016-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Sylwester Kocjan <s.kocjan@o2.pl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __SIM_PLOT_PANEL_BASE_H
|
||||
#define __SIM_PLOT_PANEL_BASE_H
|
||||
|
||||
#include "sim_types.h"
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
|
||||
|
||||
class SIM_PANEL_BASE : public wxWindow
|
||||
{
|
||||
public:
|
||||
SIM_PANEL_BASE();
|
||||
SIM_PANEL_BASE( SIM_TYPE );
|
||||
SIM_PANEL_BASE( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = 0, const wxString& name = wxPanelNameStr );
|
||||
virtual ~SIM_PANEL_BASE();
|
||||
|
||||
static bool IsPlottable( SIM_TYPE aSimType );
|
||||
|
||||
SIM_TYPE GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
private:
|
||||
const SIM_TYPE m_type;
|
||||
};
|
||||
|
||||
|
||||
class SIM_NOPLOT_PANEL : public SIM_PANEL_BASE
|
||||
{
|
||||
public:
|
||||
SIM_NOPLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = 0, const wxString& name = wxPanelNameStr );
|
||||
|
||||
virtual ~SIM_NOPLOT_PANEL();
|
||||
|
||||
private:
|
||||
wxSizer* m_sizer;
|
||||
wxStaticText* m_textInfo;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -118,7 +118,10 @@ TRACE_DESC::TRACE_DESC( const NETLIST_EXPORTER_PSPICE_SIM& aExporter, const wxSt
|
|||
wxString SIM_PLOT_FRAME::m_savedWorkbooksPath;
|
||||
|
||||
SIM_PLOT_FRAME::SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent )
|
||||
: SIM_PLOT_FRAME_BASE( aParent ), m_lastSimPlot( nullptr )
|
||||
: SIM_PLOT_FRAME_BASE( aParent ),
|
||||
m_lastSimPlot( nullptr ),
|
||||
m_welcomePanel( nullptr ),
|
||||
m_plotNumber( 0 )
|
||||
{
|
||||
SetKiway( this, aKiway );
|
||||
m_signalsIconColorList = NULL;
|
||||
|
@ -204,7 +207,9 @@ 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_welcomePanel = new SIM_PANEL_BASE( ST_UNKNOWN, m_plotNotebook, wxID_ANY );
|
||||
m_plotNotebook->AddPage( m_welcomePanel, _( "Welcome!" ), 1, true );
|
||||
|
||||
// the settings dialog will be created later, on demand.
|
||||
// if created in the ctor, for some obscure reason, there is an issue
|
||||
|
@ -419,10 +424,9 @@ void SIM_PLOT_FRAME::fillDefaultColorList( bool aWhiteBg )
|
|||
}
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::StartSimulation()
|
||||
void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
|
||||
{
|
||||
STRING_FORMATTER formatter;
|
||||
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
|
||||
|
||||
if( !m_settingsDlg )
|
||||
m_settingsDlg = new DIALOG_SIM_SETTINGS( this );
|
||||
|
@ -430,8 +434,16 @@ void SIM_PLOT_FRAME::StartSimulation()
|
|||
m_simConsole->Clear();
|
||||
updateNetlistExporter();
|
||||
|
||||
if( plotPanel )
|
||||
m_exporter->SetSimCommand( m_plots[plotPanel].m_simCommand );
|
||||
if( aSimCommand.IsEmpty() )
|
||||
{
|
||||
SIM_PANEL_BASE* plotPanel = currentPlotWindow();
|
||||
if( plotPanel )
|
||||
m_exporter->SetSimCommand( m_plots[plotPanel].m_simCommand );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_exporter->SetSimCommand( aSimCommand );
|
||||
}
|
||||
|
||||
if( !m_exporter->Format( &formatter, m_settingsDlg->GetNetlistOptions() ) )
|
||||
{
|
||||
|
@ -464,12 +476,26 @@ bool SIM_PLOT_FRAME::IsSimulationRunning()
|
|||
}
|
||||
|
||||
|
||||
SIM_PLOT_PANEL* SIM_PLOT_FRAME::NewPlotPanel( SIM_TYPE aSimType )
|
||||
SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( SIM_TYPE aSimType )
|
||||
{
|
||||
SIM_PLOT_PANEL* plotPanel = new SIM_PLOT_PANEL( aSimType, m_plotNotebook, this, wxID_ANY );
|
||||
SIM_PANEL_BASE* plotPanel;
|
||||
|
||||
plotPanel->EnableMouseWheelPan(
|
||||
m_schematicFrame->GetCanvas()->GetViewControls()->IsMousewheelPanEnabled() );
|
||||
if( SIM_PANEL_BASE::IsPlottable( aSimType ) )
|
||||
{
|
||||
SIM_PLOT_PANEL* panel;
|
||||
panel = new SIM_PLOT_PANEL( aSimType, m_plotNotebook, this, wxID_ANY );
|
||||
|
||||
panel->GetPlotWin()->EnableMouseWheelPan(
|
||||
m_schematicFrame->GetCanvas()->GetViewControls()->IsMousewheelPanEnabled() );
|
||||
|
||||
plotPanel = dynamic_cast<SIM_PANEL_BASE*>( panel );
|
||||
}
|
||||
else
|
||||
{
|
||||
SIM_NOPLOT_PANEL* panel;
|
||||
panel = new SIM_NOPLOT_PANEL( aSimType, m_plotNotebook, wxID_ANY );
|
||||
plotPanel = dynamic_cast<SIM_PANEL_BASE*>( panel );
|
||||
}
|
||||
|
||||
if( m_welcomePanel )
|
||||
{
|
||||
|
@ -477,9 +503,10 @@ SIM_PLOT_PANEL* SIM_PLOT_FRAME::NewPlotPanel( SIM_TYPE aSimType )
|
|||
m_welcomePanel = nullptr;
|
||||
}
|
||||
|
||||
m_plotNotebook->AddPage( plotPanel, wxString::Format( _( "Plot%u" ),
|
||||
(unsigned int) m_plotNotebook->GetPageCount() + 1 ), true );
|
||||
wxString pageTitle( m_simulator->TypeToName( aSimType, true ) );
|
||||
pageTitle.Prepend( wxString::Format( _( "Plot%u - " ), (unsigned int) ++m_plotNumber ) );
|
||||
|
||||
m_plotNotebook->AddPage( dynamic_cast<wxWindow*>( plotPanel ), pageTitle, true );
|
||||
m_plots[plotPanel] = PLOT_INFO();
|
||||
|
||||
return plotPanel;
|
||||
|
@ -500,9 +527,9 @@ void SIM_PLOT_FRAME::AddCurrentPlot( const wxString& aDeviceName, const wxString
|
|||
|
||||
void SIM_PLOT_FRAME::AddTuner( SCH_COMPONENT* aComponent )
|
||||
{
|
||||
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
|
||||
SIM_PANEL_BASE* plotPanel = currentPlotWindow();
|
||||
|
||||
if( !plotPanel )
|
||||
if( !plotPanel || plotPanel == m_welcomePanel )
|
||||
return;
|
||||
|
||||
// For now limit the tuner tool to RLC components
|
||||
|
@ -550,9 +577,11 @@ void SIM_PLOT_FRAME::RemoveTuner( TUNER_SLIDER* aTuner, bool aErase )
|
|||
|
||||
SIM_PLOT_PANEL* SIM_PLOT_FRAME::CurrentPlot() const
|
||||
{
|
||||
wxWindow* curPage = m_plotNotebook->GetCurrentPage();
|
||||
SIM_PANEL_BASE* curPage = currentPlotWindow();
|
||||
|
||||
return ( curPage == m_welcomePanel ) ? nullptr : static_cast<SIM_PLOT_PANEL*>( curPage );
|
||||
return ( ( !curPage || curPage->GetType() == ST_UNKNOWN ) ?
|
||||
nullptr :
|
||||
dynamic_cast<SIM_PLOT_PANEL*>( curPage ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -572,7 +601,7 @@ void SIM_PLOT_FRAME::addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const
|
|||
m_simConsole->SetInsertionPointEnd();
|
||||
return;
|
||||
}
|
||||
else if( !SIM_PLOT_PANEL::IsPlottable( simType ) )
|
||||
else if( !SIM_PANEL_BASE::IsPlottable( simType ) )
|
||||
{
|
||||
m_simConsole->AppendText( _( "Error: simulation type doesn't support plotting!\n" ) );
|
||||
m_simConsole->SetInsertionPointEnd();
|
||||
|
@ -583,7 +612,7 @@ void SIM_PLOT_FRAME::addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const
|
|||
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
|
||||
|
||||
if( !plotPanel || plotPanel->GetType() != simType )
|
||||
plotPanel = NewPlotPanel( simType );
|
||||
plotPanel = dynamic_cast<SIM_PLOT_PANEL*>( NewPlotPanel( simType ) );
|
||||
|
||||
TRACE_DESC descriptor( *m_exporter, aName, aType, aParam );
|
||||
|
||||
|
@ -630,10 +659,11 @@ void SIM_PLOT_FRAME::removePlot( const wxString& aPlotName, bool aErase )
|
|||
|
||||
wxASSERT( plotPanel->TraceShown( aPlotName ) );
|
||||
plotPanel->DeleteTrace( aPlotName );
|
||||
plotPanel->Fit();
|
||||
plotPanel->GetPlotWin()->Fit();
|
||||
|
||||
updateSignalList();
|
||||
updateCursors();
|
||||
wxCommandEvent dummy;
|
||||
onCursorUpdate( dummy );
|
||||
}
|
||||
|
||||
|
||||
|
@ -646,10 +676,10 @@ void SIM_PLOT_FRAME::updateNetlistExporter()
|
|||
bool SIM_PLOT_FRAME::updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL* aPanel )
|
||||
{
|
||||
SIM_TYPE simType = m_exporter->GetSimType();
|
||||
wxString spiceVector = m_exporter->GetSpiceVector( aDescriptor.GetName(),
|
||||
aDescriptor.GetType(), aDescriptor.GetParam() );
|
||||
wxString spiceVector = m_exporter->ComponentToVector(
|
||||
aDescriptor.GetName(), aDescriptor.GetType(), aDescriptor.GetParam() );
|
||||
|
||||
if( !SIM_PLOT_PANEL::IsPlottable( simType ) )
|
||||
if( !SIM_PANEL_BASE::IsPlottable( simType ) )
|
||||
{
|
||||
// There is no plot to be shown
|
||||
m_simulator->Command( wxString::Format( "print %s", spiceVector ).ToStdString() );
|
||||
|
@ -760,13 +790,13 @@ bool SIM_PLOT_FRAME::updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL*
|
|||
|
||||
void SIM_PLOT_FRAME::updateSignalList()
|
||||
{
|
||||
m_signals->ClearAll();
|
||||
|
||||
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
|
||||
|
||||
if( !plotPanel )
|
||||
return;
|
||||
|
||||
m_signals->ClearAll();
|
||||
|
||||
wxSize size = m_signals->GetClientSize();
|
||||
m_signals->AppendColumn( _( "Signal" ), wxLIST_FORMAT_LEFT, size.x );
|
||||
|
||||
|
@ -824,12 +854,6 @@ void SIM_PLOT_FRAME::updateSignalList()
|
|||
}
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::updateCursors()
|
||||
{
|
||||
wxQueueEvent( this, new wxCommandEvent( EVT_SIM_CURSOR_UPDATE ) );
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::updateTuners()
|
||||
{
|
||||
const auto& spiceItems = m_exporter->GetSpiceItems();
|
||||
|
@ -891,9 +915,9 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath )
|
|||
if( !file.GetNextLine().ToLong( &plotType ) )
|
||||
return false;
|
||||
|
||||
SIM_PLOT_PANEL* plotPanel = NewPlotPanel( (SIM_TYPE) plotType );
|
||||
SIM_PANEL_BASE* plotPanel = NewPlotPanel( (SIM_TYPE) plotType );
|
||||
m_plots[plotPanel].m_simCommand = file.GetNextLine();
|
||||
StartSimulation();
|
||||
StartSimulation( m_plots[plotPanel].m_simCommand );
|
||||
|
||||
// Perform simulation, so plots can be added with values
|
||||
do
|
||||
|
@ -952,19 +976,22 @@ bool SIM_PLOT_FRAME::saveWorkbook( const wxString& aPath )
|
|||
file.Create();
|
||||
}
|
||||
|
||||
file.AddLine( wxString::Format( "%lu", m_plots.size() ) );
|
||||
file.AddLine( wxString::Format( "%llu", m_plots.size() ) );
|
||||
|
||||
for( const auto& plot : m_plots )
|
||||
{
|
||||
file.AddLine( wxString::Format( "%d", plot.first->GetType() ) );
|
||||
file.AddLine( plot.second.m_simCommand );
|
||||
file.AddLine( wxString::Format( "%lu", plot.second.m_traces.size() ) );
|
||||
|
||||
for( const auto& trace : plot.second.m_traces )
|
||||
if( plot.first )
|
||||
{
|
||||
file.AddLine( wxString::Format( "%d", trace.second.GetType() ) );
|
||||
file.AddLine( trace.second.GetName() );
|
||||
file.AddLine( trace.second.GetParam() );
|
||||
file.AddLine( wxString::Format( "%d", plot.first->GetType() ) );
|
||||
file.AddLine( plot.second.m_simCommand );
|
||||
file.AddLine( wxString::Format( "%llu", plot.second.m_traces.size() ) );
|
||||
|
||||
for( const auto& trace : plot.second.m_traces )
|
||||
{
|
||||
file.AddLine( wxString::Format( "%d", trace.second.GetType() ) );
|
||||
file.AddLine( trace.second.GetName() );
|
||||
file.AddLine( trace.second.GetParam() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1000,10 +1027,10 @@ void SIM_PLOT_FRAME::menuNewPlot( wxCommandEvent& aEvent )
|
|||
{
|
||||
SIM_TYPE type = m_exporter->GetSimType();
|
||||
|
||||
if( SIM_PLOT_PANEL::IsPlottable( type ) )
|
||||
if( SIM_PANEL_BASE::IsPlottable( type ) )
|
||||
{
|
||||
SIM_PLOT_PANEL* prevPlot = CurrentPlot();
|
||||
SIM_PLOT_PANEL* newPlot = NewPlotPanel( type );
|
||||
SIM_PLOT_PANEL* newPlot = dynamic_cast<SIM_PLOT_PANEL*>( NewPlotPanel( type ) );
|
||||
|
||||
// If the previous plot had the same type, copy the simulation command
|
||||
if( prevPlot )
|
||||
|
@ -1056,7 +1083,7 @@ void SIM_PLOT_FRAME::menuSaveImage( wxCommandEvent& event )
|
|||
if( saveDlg.ShowModal() == wxID_CANCEL )
|
||||
return;
|
||||
|
||||
CurrentPlot()->SaveScreenshot( saveDlg.GetPath(), wxBITMAP_TYPE_PNG );
|
||||
CurrentPlot()->GetPlotWin()->SaveScreenshot( saveDlg.GetPath(), wxBITMAP_TYPE_PNG );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1106,21 +1133,21 @@ void SIM_PLOT_FRAME::menuSaveCsv( wxCommandEvent& event )
|
|||
void SIM_PLOT_FRAME::menuZoomIn( wxCommandEvent& event )
|
||||
{
|
||||
if( CurrentPlot() )
|
||||
CurrentPlot()->ZoomIn();
|
||||
CurrentPlot()->GetPlotWin()->ZoomIn();
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::menuZoomOut( wxCommandEvent& event )
|
||||
{
|
||||
if( CurrentPlot() )
|
||||
CurrentPlot()->ZoomOut();
|
||||
CurrentPlot()->GetPlotWin()->ZoomOut();
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::menuZoomFit( wxCommandEvent& event )
|
||||
{
|
||||
if( CurrentPlot() )
|
||||
CurrentPlot()->Fit();
|
||||
CurrentPlot()->GetPlotWin()->Fit();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1201,21 +1228,21 @@ void SIM_PLOT_FRAME::onPlotClose( wxAuiNotebookEvent& event )
|
|||
if( idx == wxNOT_FOUND )
|
||||
return;
|
||||
|
||||
SIM_PLOT_PANEL* plotPanel = dynamic_cast<SIM_PLOT_PANEL*>( m_plotNotebook->GetPage( idx ) );
|
||||
|
||||
if( !plotPanel )
|
||||
return;
|
||||
SIM_PANEL_BASE* plotPanel =
|
||||
dynamic_cast<SIM_PANEL_BASE*>( m_plotNotebook->GetPage( idx ) );
|
||||
|
||||
m_plots.erase( plotPanel );
|
||||
updateSignalList();
|
||||
updateCursors();
|
||||
wxCommandEvent dummy;
|
||||
onCursorUpdate( dummy );
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_FRAME::onPlotChanged( wxAuiNotebookEvent& event )
|
||||
{
|
||||
updateSignalList();
|
||||
updateCursors();
|
||||
wxCommandEvent dummy;
|
||||
onCursorUpdate( dummy );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1258,7 +1285,7 @@ void SIM_PLOT_FRAME::onSimulate( wxCommandEvent& event )
|
|||
|
||||
void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
|
||||
{
|
||||
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
|
||||
SIM_PANEL_BASE* plotPanelWindow = currentPlotWindow();
|
||||
|
||||
// Initial processing is required to e.g. display a list of power sources
|
||||
updateNetlistExporter();
|
||||
|
@ -1272,8 +1299,8 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
|
|||
if( !m_settingsDlg )
|
||||
m_settingsDlg = new DIALOG_SIM_SETTINGS( this );
|
||||
|
||||
if( plotPanel )
|
||||
m_settingsDlg->SetSimCommand( m_plots[plotPanel].m_simCommand );
|
||||
if( plotPanelWindow != m_welcomePanel )
|
||||
m_settingsDlg->SetSimCommand( m_plots[plotPanelWindow].m_simCommand );
|
||||
|
||||
m_settingsDlg->SetNetlistExporter( m_exporter.get() );
|
||||
|
||||
|
@ -1283,12 +1310,12 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
|
|||
SIM_TYPE newSimType = NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( newCommand );
|
||||
|
||||
// If it is a new simulation type, open a new plot
|
||||
if( !plotPanel || ( plotPanel && plotPanel->GetType() != newSimType ) )
|
||||
if( !plotPanelWindow || ( plotPanelWindow && plotPanelWindow->GetType() != newSimType ) )
|
||||
{
|
||||
plotPanel = NewPlotPanel( newSimType );
|
||||
plotPanelWindow = NewPlotPanel( newSimType );
|
||||
}
|
||||
|
||||
m_plots[plotPanel].m_simCommand = newCommand;
|
||||
m_plots[plotPanelWindow].m_simCommand = newCommand;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1299,7 +1326,7 @@ void SIM_PLOT_FRAME::onAddSignal( wxCommandEvent& event )
|
|||
|
||||
if( !plotPanel || !m_exporter || plotPanel->GetType() != m_exporter->GetSimType() )
|
||||
{
|
||||
DisplayInfoMessage( this, _( "You need to run simulation first." ) );
|
||||
DisplayInfoMessage( this, _( "You need to run plot-providing simulation first." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1455,18 +1482,19 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
|
|||
if( simType == ST_UNKNOWN )
|
||||
return;
|
||||
|
||||
SIM_PLOT_PANEL* plotPanel = CurrentPlot();
|
||||
SIM_PANEL_BASE* plotPanelWindow = currentPlotWindow();
|
||||
|
||||
if( !plotPanel || plotPanel->GetType() != simType )
|
||||
plotPanel = NewPlotPanel( simType );
|
||||
if( !plotPanelWindow || plotPanelWindow->GetType() != simType )
|
||||
plotPanelWindow = NewPlotPanel( simType );
|
||||
|
||||
if( IsSimulationRunning() )
|
||||
return;
|
||||
|
||||
// If there are any signals plotted, update them
|
||||
if( SIM_PLOT_PANEL::IsPlottable( simType ) )
|
||||
if( SIM_PANEL_BASE::IsPlottable( simType ) )
|
||||
{
|
||||
TRACE_MAP& traceMap = m_plots[plotPanel].m_traces;
|
||||
TRACE_MAP& traceMap = m_plots[plotPanelWindow].m_traces;
|
||||
SIM_PLOT_PANEL* plotPanel = dynamic_cast<SIM_PLOT_PANEL*>( plotPanelWindow );
|
||||
|
||||
for( auto it = traceMap.begin(); it != traceMap.end(); /* iteration occurs in the loop */)
|
||||
{
|
||||
|
@ -1482,18 +1510,33 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
|
|||
}
|
||||
|
||||
updateSignalList();
|
||||
plotPanel->UpdateAll();
|
||||
plotPanel->GetPlotWin()->UpdateAll();
|
||||
plotPanel->ResetScales();
|
||||
}
|
||||
else
|
||||
else if( simType == ST_OP )
|
||||
{
|
||||
/// @todo do not make it hardcoded for ngspice
|
||||
for( const auto& net : m_exporter->GetNetIndexMap() )
|
||||
{
|
||||
int node = net.second;
|
||||
m_simConsole->AppendText( _( "\n\nSimulation results:\n\n" ) );
|
||||
m_simConsole->SetInsertionPointEnd();
|
||||
|
||||
if( node > 0 )
|
||||
m_simulator->Command( wxString::Format( "print v(%d)", node ).ToStdString() );
|
||||
for( const auto& vec : m_simulator->AllPlots() )
|
||||
{
|
||||
double val = m_simulator->GetRealPlot( vec, 1 ).at( 0 );
|
||||
|
||||
wxString outLine, signal;
|
||||
SIM_PLOT_TYPE type = m_exporter->VectorToSignal( vec, signal );
|
||||
|
||||
const size_t tab = 25; //characters
|
||||
size_t padding = ( signal.length() < tab ) ? ( tab - signal.length() ) : 1;
|
||||
|
||||
outLine.Printf( wxT( "%s%s" ), ( signal + wxT( ":" ) ).Pad( padding, wxUniChar( ' ' ) ),
|
||||
SPICE_VALUE( val ).ToSpiceString() );
|
||||
|
||||
outLine.Append( type == SPT_CURRENT ? "A\n" : "V\n" );
|
||||
|
||||
m_simConsole->AppendText( outLine );
|
||||
m_simConsole->SetInsertionPointEnd();
|
||||
|
||||
// @todo display calculated values on the schematic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,10 @@ class SCH_COMPONENT;
|
|||
|
||||
class SPICE_SIMULATOR;
|
||||
class NETLIST_EXPORTER_PSPICE_SIM;
|
||||
class SIM_PLOT_PANEL;
|
||||
|
||||
#include "sim_plot_panel.h"
|
||||
#include "sim_panel_base.h"
|
||||
|
||||
class SIM_THREAD_REPORTER;
|
||||
class TUNER_SLIDER;
|
||||
|
||||
|
@ -117,6 +120,7 @@ private:
|
|||
wxString m_title;
|
||||
};
|
||||
|
||||
|
||||
/** Implementing SIM_PLOT_FRAME_BASE */
|
||||
class SIM_PLOT_FRAME : public SIM_PLOT_FRAME_BASE
|
||||
{
|
||||
|
@ -125,7 +129,7 @@ public:
|
|||
SIM_PLOT_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||
~SIM_PLOT_FRAME();
|
||||
|
||||
void StartSimulation();
|
||||
void StartSimulation( const wxString& aSimCommand = wxEmptyString );
|
||||
void StopSimulation();
|
||||
bool IsSimulationRunning();
|
||||
|
||||
|
@ -135,7 +139,7 @@ public:
|
|||
* @param aSimType is requested simulation type.
|
||||
* @return The new plot panel.
|
||||
*/
|
||||
SIM_PLOT_PANEL* NewPlotPanel( SIM_TYPE aSimType );
|
||||
SIM_PANEL_BASE* NewPlotPanel( SIM_TYPE aSimType );
|
||||
|
||||
/**
|
||||
* @brief Adds a voltage plot for a given net name.
|
||||
|
@ -211,6 +215,14 @@ private:
|
|||
*/
|
||||
void fillDefaultColorList( bool aWhiteBg );
|
||||
|
||||
/**
|
||||
* @brief Returns the currently opened plot panel (or NULL if there is none).
|
||||
*/
|
||||
SIM_PANEL_BASE* currentPlotWindow() const
|
||||
{
|
||||
return dynamic_cast<SIM_PANEL_BASE*>( m_plotNotebook->GetCurrentPage() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a new plot to the current panel.
|
||||
* @param aName is the device/net name.
|
||||
|
@ -245,11 +257,6 @@ private:
|
|||
*/
|
||||
void updateSignalList();
|
||||
|
||||
/**
|
||||
* @brief Updates the cursor values list.
|
||||
*/
|
||||
void updateCursors();
|
||||
|
||||
/**
|
||||
* @brief Filters out tuners for components that do not exist anymore.
|
||||
* Decisions are based on the current NETLIST_EXPORTER data.
|
||||
|
@ -359,7 +366,7 @@ private:
|
|||
};
|
||||
|
||||
///> Map of plot panels and associated data
|
||||
std::map<SIM_PLOT_PANEL*, PLOT_INFO> m_plots;
|
||||
std::map<SIM_PANEL_BASE*, PLOT_INFO> m_plots;
|
||||
|
||||
///> List of currently displayed tuners
|
||||
std::list<TUNER_SLIDER*> m_tuners;
|
||||
|
@ -400,12 +407,16 @@ private:
|
|||
///> A string to store the path of saved workbooks during a session
|
||||
static wxString m_savedWorkbooksPath;
|
||||
|
||||
///> Info panel
|
||||
SIM_PANEL_BASE* m_welcomePanel;
|
||||
|
||||
// Variables for temporary storage:
|
||||
int m_splitterLeftRightSashPosition;
|
||||
int m_splitterPlotAndConsoleSashPosition;
|
||||
int m_splitterSignalsSashPosition;
|
||||
int m_splitterTuneValuesSashPosition;
|
||||
bool m_plotUseWhiteBg;
|
||||
unsigned int m_plotNumber;
|
||||
|
||||
///> The color list to draw traces, bg, fg, axis...
|
||||
std::vector<wxColour> m_colorList;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jul 10 2019)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -141,39 +141,6 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const
|
|||
m_plotNotebook = new wxAuiNotebook( m_plotPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_CLOSE_ON_ALL_TABS|wxAUI_NB_MIDDLE_CLICK_CLOSE|wxAUI_NB_TAB_MOVE|wxAUI_NB_TAB_SPLIT|wxAUI_NB_TOP );
|
||||
m_plotNotebook->SetMinSize( wxSize( 200,-1 ) );
|
||||
|
||||
m_welcomePanel = new wxPanel( m_plotNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
m_sizer8 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
|
||||
m_sizer8->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizer81;
|
||||
bSizer81 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
|
||||
bSizer81->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_staticTextInfo = new wxStaticText( m_welcomePanel, wxID_ANY, _("Start the simulation by clicking the Run Simulation button"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextInfo->Wrap( -1 );
|
||||
m_staticTextInfo->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
|
||||
m_staticTextInfo->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
|
||||
|
||||
bSizer81->Add( m_staticTextInfo, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizer81->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_sizer8->Add( bSizer81, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_sizer8->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_welcomePanel->SetSizer( m_sizer8 );
|
||||
m_welcomePanel->Layout();
|
||||
m_sizer8->Fit( m_welcomePanel );
|
||||
m_plotNotebook->AddPage( m_welcomePanel, _("a page"), false, wxNullBitmap );
|
||||
|
||||
m_sizerPlot->Add( m_plotNotebook, 1, wxEXPAND, 5 );
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
<property name="file">sim_plot_frame_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="image_path_wrapper_function_name"></property>
|
||||
<property name="indent_with_spaces"></property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">SpiceWindow</property>
|
||||
|
@ -26,7 +25,6 @@
|
|||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_array_enum">0</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Frame" expanded="1">
|
||||
|
@ -753,181 +751,6 @@
|
|||
<property name="window_style"></property>
|
||||
<event name="OnAuiNotebookPageChanged">onPlotChanged</event>
|
||||
<event name="OnAuiNotebookPageClose">onPlotClose</event>
|
||||
<object class="auinotebookpage" expanded="0">
|
||||
<property name="bitmap"></property>
|
||||
<property name="label">a page</property>
|
||||
<property name="select">0</property>
|
||||
<object class="wxPanel" expanded="0">
|
||||
<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_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="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_welcomePanel</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="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style">wxTAB_TRAVERSAL</property>
|
||||
<object class="wxBoxSizer" expanded="0">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_sizer8</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">protected</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="0">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="0">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizer81</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="0">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="0">
|
||||
<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_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">wxSYS_COLOUR_GRAYTEXT</property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font">,90,92,-1,70,0</property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Start the simulation by clicking the Run Simulation button</property>
|
||||
<property name="markup">0</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_staticTextInfo</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="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="0">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="spacer" expanded="0">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jul 10 2019)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -7,30 +7,28 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
class wxListView;
|
||||
|
||||
#include "kiway_player.h"
|
||||
#include <wx/string.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/toolbar.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/aui/auibook.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/frame.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/intl.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/toolbar.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -74,9 +72,6 @@ class SIM_PLOT_FRAME_BASE : public KIWAY_PLAYER
|
|||
wxPanel* m_plotPanel;
|
||||
wxBoxSizer* m_sizerPlot;
|
||||
wxAuiNotebook* m_plotNotebook;
|
||||
wxPanel* m_welcomePanel;
|
||||
wxBoxSizer* m_sizer8;
|
||||
wxStaticText* m_staticTextInfo;
|
||||
wxPanel* m_panelConsole;
|
||||
wxBoxSizer* m_sizerConsole;
|
||||
wxTextCtrl* m_simConsole;
|
||||
|
|
|
@ -364,25 +364,25 @@ void CURSOR::UpdateReference()
|
|||
|
||||
|
||||
SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame,
|
||||
wxWindowID id, const wxPoint& pos,
|
||||
const wxSize& size, long style, const wxString& name )
|
||||
: mpWindow( parent, id, pos, size, style ),
|
||||
wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name )
|
||||
: SIM_PANEL_BASE( aType, parent, id, pos, size, style, name ),
|
||||
m_colorIdx( 0 ),
|
||||
m_axis_x( nullptr ),
|
||||
m_axis_y1( nullptr ),
|
||||
m_axis_y2( nullptr ),
|
||||
m_dotted_cp( false ),
|
||||
m_type( aType ),
|
||||
m_masterFrame( aMainFrame )
|
||||
{
|
||||
LimitView( true );
|
||||
SetMargins( 50, 80, 50, 80 );
|
||||
m_sizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_plotWin = new mpWindow( this, wxID_ANY, pos, size, style );
|
||||
|
||||
SetColourTheme( GetPlotColor( SIM_BG_COLOR ),
|
||||
GetPlotColor( SIM_FG_COLOR ),
|
||||
GetPlotColor( SIM_AXIS_COLOR ) );
|
||||
m_plotWin->LimitView( true );
|
||||
m_plotWin->SetMargins( 50, 80, 50, 80 );
|
||||
|
||||
switch( m_type )
|
||||
m_plotWin->SetColourTheme( GetPlotColor( SIM_BG_COLOR ), GetPlotColor( SIM_FG_COLOR ),
|
||||
GetPlotColor( SIM_AXIS_COLOR ) );
|
||||
|
||||
switch( GetType() )
|
||||
{
|
||||
case ST_AC:
|
||||
m_axis_x = new FREQUENCY_LOG_SCALE( _( "Frequency" ), mpALIGN_BOTTOM );
|
||||
|
@ -419,30 +419,33 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, SIM_PLOT_FRAME
|
|||
m_axis_x->SetTicks( false );
|
||||
m_axis_x->SetNameAlign ( mpALIGN_BOTTOM );
|
||||
|
||||
AddLayer( m_axis_x );
|
||||
m_plotWin->AddLayer( m_axis_x );
|
||||
}
|
||||
|
||||
if( m_axis_y1 )
|
||||
{
|
||||
m_axis_y1->SetTicks( false );
|
||||
m_axis_y1->SetNameAlign ( mpALIGN_LEFT );
|
||||
AddLayer( m_axis_y1 );
|
||||
m_plotWin->AddLayer( m_axis_y1 );
|
||||
}
|
||||
|
||||
if( m_axis_y2 )
|
||||
{
|
||||
m_axis_y2->SetTicks( false );
|
||||
m_axis_y2->SetNameAlign ( mpALIGN_RIGHT );
|
||||
AddLayer( m_axis_y2 );
|
||||
m_plotWin->AddLayer( m_axis_y2 );
|
||||
}
|
||||
|
||||
// a mpInfoLegend displays le name of traces on the left top panel corner:
|
||||
m_legend = new mpInfoLegend( wxRect( 0, 40, 200, 40 ), wxTRANSPARENT_BRUSH );
|
||||
m_legend->SetVisible( false );
|
||||
AddLayer( m_legend );
|
||||
m_plotWin->AddLayer( m_legend );
|
||||
|
||||
EnableDoubleBuffer( true );
|
||||
UpdateAll();
|
||||
m_plotWin->EnableDoubleBuffer( true );
|
||||
m_plotWin->UpdateAll();
|
||||
|
||||
m_sizer->Add( m_plotWin, 1, wxALL | wxEXPAND, 1 );
|
||||
SetSizer( m_sizer );
|
||||
}
|
||||
|
||||
|
||||
|
@ -455,11 +458,10 @@ SIM_PLOT_PANEL::~SIM_PLOT_PANEL()
|
|||
void SIM_PLOT_PANEL::UpdatePlotColors()
|
||||
{
|
||||
// Update bg and fg colors:
|
||||
SetColourTheme( GetPlotColor( SIM_BG_COLOR ),
|
||||
GetPlotColor( SIM_FG_COLOR ),
|
||||
GetPlotColor( SIM_AXIS_COLOR ) );
|
||||
m_plotWin->SetColourTheme( GetPlotColor( SIM_BG_COLOR ), GetPlotColor( SIM_FG_COLOR ),
|
||||
GetPlotColor( SIM_AXIS_COLOR ) );
|
||||
|
||||
UpdateAll();
|
||||
m_plotWin->UpdateAll();
|
||||
}
|
||||
|
||||
|
||||
|
@ -469,21 +471,6 @@ wxColour SIM_PLOT_PANEL::GetPlotColor( int aIndex )
|
|||
}
|
||||
|
||||
|
||||
bool SIM_PLOT_PANEL::IsPlottable( SIM_TYPE aSimType )
|
||||
{
|
||||
switch( aSimType )
|
||||
{
|
||||
case ST_AC:
|
||||
case ST_DC:
|
||||
case ST_TRANSIENT:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SIM_PLOT_PANEL::UpdateTraceStyle( TRACE* trace )
|
||||
{
|
||||
int flags = trace->GetFlags();
|
||||
|
@ -505,7 +492,7 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
|
|||
|
||||
if( addedNewEntry )
|
||||
{
|
||||
if( m_type == ST_TRANSIENT )
|
||||
if( GetType() == ST_TRANSIENT )
|
||||
{
|
||||
bool hasVoltageTraces = false;
|
||||
|
||||
|
@ -532,12 +519,12 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
|
|||
|
||||
// It is a trick to keep legend & coords always on the top
|
||||
for( mpLayer* l : m_topLevel )
|
||||
DelLayer( l );
|
||||
m_plotWin->DelLayer( l );
|
||||
|
||||
AddLayer( (mpLayer*) trace );
|
||||
m_plotWin->AddLayer( (mpLayer*) trace );
|
||||
|
||||
for( mpLayer* l : m_topLevel )
|
||||
AddLayer( l );
|
||||
m_plotWin->AddLayer( l );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -546,7 +533,7 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
|
|||
|
||||
std::vector<double> tmp( aY, aY + aPoints );
|
||||
|
||||
if( m_type == ST_AC )
|
||||
if( GetType() == ST_AC )
|
||||
{
|
||||
if( aFlags & SPT_AC_PHASE )
|
||||
{
|
||||
|
@ -569,7 +556,7 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
|
|||
|
||||
trace->SetFlags( aFlags );
|
||||
|
||||
UpdateAll();
|
||||
m_plotWin->UpdateAll();
|
||||
|
||||
return addedNewEntry;
|
||||
}
|
||||
|
@ -585,9 +572,9 @@ bool SIM_PLOT_PANEL::DeleteTrace( const wxString& aName )
|
|||
m_traces.erase( it );
|
||||
|
||||
if( CURSOR* cursor = trace->GetCursor() )
|
||||
DelLayer( cursor, true );
|
||||
m_plotWin->DelLayer( cursor, true );
|
||||
|
||||
DelLayer( trace, true, true );
|
||||
m_plotWin->DelLayer( trace, true, true );
|
||||
ResetScales();
|
||||
|
||||
return true;
|
||||
|
@ -627,16 +614,19 @@ void SIM_PLOT_PANEL::EnableCursor( const wxString& aName, bool aEnable )
|
|||
if( aEnable )
|
||||
{
|
||||
CURSOR* c = new CURSOR( t, this );
|
||||
int plotCenter = GetMarginLeft() + ( GetXScreen() - GetMarginLeft() - GetMarginRight() ) / 2;
|
||||
int plotCenter = GetPlotWin()->GetMarginLeft()
|
||||
+ ( GetPlotWin()->GetXScreen() - GetPlotWin()->GetMarginLeft()
|
||||
- GetPlotWin()->GetMarginRight() )
|
||||
/ 2;
|
||||
c->SetX( plotCenter );
|
||||
t->SetCursor( c );
|
||||
AddLayer( c );
|
||||
m_plotWin->AddLayer( c );
|
||||
}
|
||||
else
|
||||
{
|
||||
CURSOR* c = t->GetCursor();
|
||||
t->SetCursor( NULL );
|
||||
DelLayer( c, true );
|
||||
m_plotWin->DelLayer( c, true );
|
||||
}
|
||||
|
||||
// Notify the parent window about the changes
|
||||
|
|
|
@ -27,9 +27,11 @@
|
|||
#ifndef __SIM_PLOT_PANEL_H
|
||||
#define __SIM_PLOT_PANEL_H
|
||||
|
||||
#include <widgets/mathplot.h>
|
||||
#include <map>
|
||||
#include "sim_types.h"
|
||||
#include <map>
|
||||
#include <widgets/mathplot.h>
|
||||
#include <wx/sizer.h>
|
||||
#include "sim_panel_base.h"
|
||||
|
||||
class SIM_PLOT_FRAME;
|
||||
class SIM_PLOT_PANEL;
|
||||
|
@ -163,14 +165,14 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
class SIM_PLOT_PANEL : public mpWindow
|
||||
class SIM_PLOT_PANEL : public SIM_PANEL_BASE
|
||||
{
|
||||
public:
|
||||
SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, SIM_PLOT_FRAME* aMainFrame,
|
||||
wxWindowID id, const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxPanelNameStr );
|
||||
|
||||
~SIM_PLOT_PANEL();
|
||||
virtual ~SIM_PLOT_PANEL();
|
||||
|
||||
///> set the pointer to the sim plot frame
|
||||
void SetMasterFrame( SIM_PLOT_FRAME* aFrame )
|
||||
|
@ -178,13 +180,6 @@ public:
|
|||
m_masterFrame = aFrame;
|
||||
}
|
||||
|
||||
SIM_TYPE GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
static bool IsPlottable( SIM_TYPE aSimType );
|
||||
|
||||
wxString GetLabelX() const
|
||||
{
|
||||
return m_axis_x ? m_axis_x->GetName() : "";
|
||||
|
@ -229,7 +224,7 @@ public:
|
|||
m_axis_x->SetTicks( !aEnable );
|
||||
m_axis_y1->SetTicks( !aEnable );
|
||||
m_axis_y2->SetTicks( !aEnable );
|
||||
UpdateAll();
|
||||
m_plotWin->UpdateAll();
|
||||
}
|
||||
|
||||
bool IsGridShown() const
|
||||
|
@ -244,7 +239,7 @@ public:
|
|||
void ShowLegend( bool aEnable )
|
||||
{
|
||||
m_legend->SetVisible( aEnable );
|
||||
UpdateAll();
|
||||
m_plotWin->UpdateAll();
|
||||
}
|
||||
|
||||
bool IsLegendShown() const
|
||||
|
@ -261,7 +256,7 @@ public:
|
|||
UpdateTraceStyle( tr.second );
|
||||
}
|
||||
|
||||
UpdateAll();
|
||||
m_plotWin->UpdateAll();
|
||||
}
|
||||
|
||||
bool GetDottedCurrentPhase() const
|
||||
|
@ -291,6 +286,12 @@ public:
|
|||
///> Update plot colors
|
||||
void UpdatePlotColors();
|
||||
|
||||
///> Getter for math plot window
|
||||
mpWindow* GetPlotWin() const
|
||||
{
|
||||
return m_plotWin;
|
||||
}
|
||||
|
||||
private:
|
||||
///> @return a new color from the palette
|
||||
wxColour generateColor();
|
||||
|
@ -298,6 +299,10 @@ private:
|
|||
// Color index to get a new color from the palette
|
||||
unsigned int m_colorIdx;
|
||||
|
||||
// Top-level plot window
|
||||
mpWindow* m_plotWin;
|
||||
wxBoxSizer* m_sizer;
|
||||
|
||||
// Traces to be plotted
|
||||
std::map<wxString, TRACE*> m_traces;
|
||||
|
||||
|
@ -310,8 +315,6 @@ private:
|
|||
|
||||
std::vector<mpLayer*> m_topLevel;
|
||||
|
||||
const SIM_TYPE m_type;
|
||||
|
||||
SIM_PLOT_FRAME* m_masterFrame;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,24 +26,36 @@
|
|||
#define SIM_TYPES_H
|
||||
|
||||
///> Possible simulation types
|
||||
enum SIM_TYPE {
|
||||
ST_UNKNOWN, ST_AC, ST_DC, ST_DISTORTION, ST_NOISE, ST_OP,
|
||||
ST_POLE_ZERO, ST_SENSITIVITY, ST_TRANS_FUNC, ST_TRANSIENT
|
||||
enum SIM_TYPE
|
||||
{
|
||||
ST_UNKNOWN,
|
||||
ST_AC,
|
||||
ST_DC,
|
||||
ST_DISTORTION,
|
||||
ST_NOISE,
|
||||
ST_OP,
|
||||
ST_POLE_ZERO,
|
||||
ST_SENSITIVITY,
|
||||
ST_TRANS_FUNC,
|
||||
ST_TRANSIENT
|
||||
};
|
||||
|
||||
///> Possible plot types
|
||||
enum SIM_PLOT_TYPE {
|
||||
enum SIM_PLOT_TYPE
|
||||
{
|
||||
// Y axis
|
||||
SPT_VOLTAGE = 0x01,
|
||||
SPT_CURRENT = 0x02,
|
||||
SPT_AC_PHASE = 0x04,
|
||||
SPT_AC_MAG = 0x08,
|
||||
SPT_VOLTAGE = 0x01,
|
||||
SPT_CURRENT = 0x02,
|
||||
SPT_AC_PHASE = 0x04,
|
||||
SPT_AC_MAG = 0x08,
|
||||
|
||||
// X axis
|
||||
SPT_TIME = 0x10,
|
||||
SPT_LIN_FREQUENCY = 0x20,
|
||||
SPT_LOG_FREQUENCY = 0x20,
|
||||
SPT_SWEEP = 0x40
|
||||
SPT_TIME = 0x10,
|
||||
SPT_LIN_FREQUENCY = 0x20,
|
||||
SPT_LOG_FREQUENCY = 0x20,
|
||||
SPT_SWEEP = 0x40,
|
||||
|
||||
SPT_UNKNOWN = 0x00
|
||||
};
|
||||
|
||||
#endif /* SIM_TYPES_H */
|
||||
|
|
|
@ -45,3 +45,39 @@ std::shared_ptr<SPICE_SIMULATOR> SPICE_SIMULATOR::CreateInstance( const std::str
|
|||
return NULL;
|
||||
}
|
||||
|
||||
wxString SPICE_SIMULATOR::TypeToName( SIM_TYPE aType, bool aShortName )
|
||||
{
|
||||
switch( aType )
|
||||
{
|
||||
case ST_OP:
|
||||
return aShortName ? wxT( "OP" ) : _( "Operating Point" );
|
||||
|
||||
case ST_AC:
|
||||
return "AC";
|
||||
|
||||
case ST_DC:
|
||||
return aShortName ? wxT( "DC" ) : _( "DC Sweep" );
|
||||
|
||||
case ST_TRANSIENT:
|
||||
return aShortName ? wxT( "TRAN" ) : _( "Transient" );
|
||||
|
||||
case ST_DISTORTION:
|
||||
return aShortName ? wxT( "DISTO" ) : _( "Distortion" );
|
||||
|
||||
case ST_NOISE:
|
||||
return aShortName ? wxT( "NOISE" ) : _( "Noise" );
|
||||
|
||||
case ST_POLE_ZERO:
|
||||
return aShortName ? wxT( "PZ" ) : _( "Pole-zero" );
|
||||
|
||||
case ST_SENSITIVITY:
|
||||
return aShortName ? wxT( "SENS" ) : _( "Sensitivity" );
|
||||
|
||||
case ST_TRANS_FUNC:
|
||||
return aShortName ? wxT( "TF" ) : _( "Transfer function" );
|
||||
|
||||
default:
|
||||
case ST_UNKNOWN:
|
||||
return aShortName ? _( "UNKNOWN!" ) : _( "Unknown" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <complex>
|
||||
#include <memory>
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
class SPICE_REPORTER;
|
||||
class SPICE_SIMULATOR;
|
||||
|
||||
|
@ -88,6 +90,13 @@ public:
|
|||
m_reporter = aReporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a list with all vectors generated in current simulation.
|
||||
* @param none
|
||||
* @return List of vector names. ?May not match to the net name elements.
|
||||
*/
|
||||
virtual std::vector<std::string> AllPlots() = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns a requested vector with complex values. If the vector is real, then
|
||||
* the imaginary part is set to 0 in all values.
|
||||
|
@ -142,6 +151,15 @@ public:
|
|||
*/
|
||||
virtual const std::string GetNetlist() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns a string with simulation name based on enum.
|
||||
* @param aType is the enum describing simulation type
|
||||
* @param aShortName if true - return is in format "TRAN", "OP".
|
||||
* if false - return is in format "Transient", "Operating Point".
|
||||
* @return String with requested name as described above.
|
||||
*/
|
||||
static wxString TypeToName( SIM_TYPE aType, bool aShortName );
|
||||
|
||||
protected:
|
||||
///> Reporter object to receive simulation log
|
||||
SPICE_REPORTER* m_reporter;
|
||||
|
|
|
@ -52,6 +52,9 @@ add_executable( qa_eeschema
|
|||
test_sch_sheet.cpp
|
||||
test_sch_sheet_path.cpp
|
||||
|
||||
# Simulation tests
|
||||
sim/test_netlist_exporter_pspice_sim.cpp
|
||||
|
||||
# Older CMakes cannot link OBJECT libraries
|
||||
# https://cmake.org/pipermail/cmake/2013-November/056263.html
|
||||
$<TARGET_OBJECTS:eeschema_kiface_objects>
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 S.Kocjan <s.kocjan@o2.pl>
|
||||
* Copyright (C) 2020 KiCad Developers, see CHANGELOG.TXT for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test suite for NETLIST_EXPORTER_PSPICE_SIM
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
#include <vector>
|
||||
#include <wx/string.h>
|
||||
|
||||
// Code under test
|
||||
#include <sim/netlist_exporter_pspice_sim.h>
|
||||
|
||||
class TEST_NETLIST_EXPORTER_PSPICE_SIM
|
||||
{
|
||||
public:
|
||||
TEST_NETLIST_EXPORTER_PSPICE_SIM()
|
||||
: m_netlist( new NETLIST_OBJECT_LIST ), m_exporter( m_netlist )
|
||||
{
|
||||
}
|
||||
|
||||
NETLIST_OBJECT_LIST* m_netlist;
|
||||
NETLIST_EXPORTER_PSPICE_SIM m_exporter;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Declare the test suite
|
||||
*/
|
||||
BOOST_FIXTURE_TEST_SUITE( NetlistExporterPspiceSim, TEST_NETLIST_EXPORTER_PSPICE_SIM )
|
||||
|
||||
|
||||
/**
|
||||
* Check if simulation command is recognised properly
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( CommandToSimType )
|
||||
{
|
||||
struct TEST_DATA
|
||||
{
|
||||
wxString command;
|
||||
SIM_TYPE type;
|
||||
};
|
||||
|
||||
std::vector<struct TEST_DATA> testData = {
|
||||
{ ".op", ST_OP },
|
||||
{ ".option TEMP=27", ST_UNKNOWN },
|
||||
{ ".tran 0 1 0.1", ST_TRANSIENT },
|
||||
{ ".tran 0 1 0.1 UIC", ST_TRANSIENT },
|
||||
{ ".ac dec 10 1 10K", ST_AC },
|
||||
{ ".ac dec 10 1K 100MEG", ST_AC },
|
||||
{ ".ac lin 100 1 100HZ", ST_AC },
|
||||
{ ".dc VIN 0.25 5.0 0.25", ST_DC },
|
||||
{ ".dc VDS 0 10 .5 VGS 0 5 1", ST_DC },
|
||||
{ ".dc VCE 0 10 .25 IB 0 10u 1u", ST_DC },
|
||||
{ ".dc RLoad 1k 2k 100", ST_DC },
|
||||
{ ".dc TEMP -15 75 5", ST_DC },
|
||||
{ ".disto dec 10 1kHz 100MEG", ST_DISTORTION },
|
||||
{ ".disto dec 10 1kHz 100MEG 0.9", ST_DISTORTION },
|
||||
{ ".noise v(5) VIN dec 10 1kHz 100MEG", ST_NOISE },
|
||||
{ ".noise v(5,3) V1 oct 8 1.0 1.0e6 1", ST_NOISE },
|
||||
{ ".pz 1 0 3 0 cur pol", ST_POLE_ZERO },
|
||||
{ ".pz 2 3 5 0 vol zer", ST_POLE_ZERO },
|
||||
{ ".pz 4 1 4 1 cur pz", ST_POLE_ZERO },
|
||||
{ ".SENS V(1,OUT)", ST_SENSITIVITY },
|
||||
{ ".SENS V(OUT) AC DEC 10 100 100k", ST_SENSITIVITY },
|
||||
{ ".SENS I(VTEST)", ST_SENSITIVITY },
|
||||
{ ".tf v(5, 3) VIN", ST_TRANS_FUNC },
|
||||
{ ".tf i(VLOAD) VIN", ST_TRANS_FUNC },
|
||||
};
|
||||
|
||||
for( auto& step : testData )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( m_exporter.CommandToSimType( wxString( step.command ) ), step.type );
|
||||
}
|
||||
|
||||
for( auto& step : testData )
|
||||
{
|
||||
step.command.Append( "\n" );
|
||||
BOOST_CHECK_EQUAL( m_exporter.CommandToSimType( wxString( step.command ) ), step.type );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check conversion from internal spice vector name to eeschema format
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( VectorToSignal )
|
||||
{
|
||||
struct TEST_DATA
|
||||
{
|
||||
std::string vector;
|
||||
wxString signal;
|
||||
SIM_PLOT_TYPE type;
|
||||
};
|
||||
|
||||
std::vector<struct TEST_DATA> testData = { { "@c3[i]", "I(C3)", SPT_CURRENT },
|
||||
{ "@r12[i]", "I(R12)", SPT_CURRENT }, { "@r7[i]", "I(R7)", SPT_CURRENT },
|
||||
{ "@l2[i]", "I(L2)", SPT_CURRENT }, { "@c2[i]", "I(C2)", SPT_CURRENT },
|
||||
{ "@r6[i]", "I(R6)", SPT_CURRENT }, { "@r5[i]", "I(R5)", SPT_CURRENT },
|
||||
{ "@r10[i]", "I(R10)", SPT_CURRENT }, { "@q3[ie]", "Ie(Q3)", SPT_CURRENT },
|
||||
{ "@q3[ic]", "Ic(Q3)", SPT_CURRENT }, { "@q3[ib]", "Ib(Q3)", SPT_CURRENT },
|
||||
{ "@r11[i]", "I(R11)", SPT_CURRENT }, { "@r8[i]", "I(R8)", SPT_CURRENT },
|
||||
{ "@q1[ie]", "Ie(Q1)", SPT_CURRENT }, { "@q1[ic]", "Ic(Q1)", SPT_CURRENT },
|
||||
{ "@q1[ib]", "Ib(Q1)", SPT_CURRENT }, { "@r1[i]", "I(R1)", SPT_CURRENT },
|
||||
{ "@l1[i]", "I(L1)", SPT_CURRENT }, { "@c4[i]", "I(C4)", SPT_CURRENT },
|
||||
{ "@r2[i]", "I(R2)", SPT_CURRENT }, { "@q2[ig]", "Ig(Q2)", SPT_CURRENT },
|
||||
{ "@q2[id]", "Id(Q2)", SPT_CURRENT }, { "@q2[is]", "Is(Q2)", SPT_CURRENT },
|
||||
{ "@v2[i]", "I(V2)", SPT_CURRENT }, { "@r9[i]", "I(R9)", SPT_CURRENT },
|
||||
{ "@c1[i]", "I(C1)", SPT_CURRENT }, { "@v1[i]", "I(V1)", SPT_CURRENT },
|
||||
{ "@r3[i]", "I(R3)", SPT_CURRENT }, { "@r4[i]", "I(R4)", SPT_CURRENT },
|
||||
{ "vout", "V(vout)", SPT_VOLTAGE }, { "net-_q3-pad2_", "V(net-_q3-pad2_)", SPT_VOLTAGE },
|
||||
{ "net-_q2-pad3_", "V(net-_q2-pad3_)", SPT_VOLTAGE },
|
||||
{ "net-_q2-pad1_", "V(net-_q2-pad1_)", SPT_VOLTAGE },
|
||||
{ "net-_q1-pad3_", "V(net-_q1-pad3_)", SPT_VOLTAGE },
|
||||
{ "net-_l2-pad1_", "V(net-_l2-pad1_)", SPT_VOLTAGE },
|
||||
{ "net-_c4-pad2_", "V(net-_c4-pad2_)", SPT_VOLTAGE },
|
||||
{ "net-_c3-pad1_", "V(net-_c3-pad1_)", SPT_VOLTAGE },
|
||||
{ "net-_c1-pad2_", "V(net-_c1-pad2_)", SPT_VOLTAGE }, { "/vin", "V(/vin)", SPT_VOLTAGE },
|
||||
{ "/vbase", "V(/vbase)", SPT_VOLTAGE }, { "+12v", "V(+12v)", SPT_VOLTAGE },
|
||||
{ "@m1[cgs]", "", SPT_UNKNOWN }, { "@d1[g11]", "", SPT_UNKNOWN },
|
||||
{ "@d1[c12]", "", SPT_UNKNOWN }, { "@d1[y21]", "", SPT_UNKNOWN },
|
||||
{ "@n1[vth0]", "", SPT_UNKNOWN }, { "@mn1[gm]", "", SPT_UNKNOWN },
|
||||
{ "@m.xmos1.xmos2.m1[vdsat]", "", SPT_UNKNOWN } };
|
||||
|
||||
for( auto& step : testData )
|
||||
{
|
||||
wxString outputSignalName;
|
||||
SIM_PLOT_TYPE retVal;
|
||||
|
||||
retVal = m_exporter.VectorToSignal( step.vector, outputSignalName );
|
||||
|
||||
BOOST_CHECK_EQUAL( retVal, step.type );
|
||||
BOOST_CHECK_EQUAL( outputSignalName.Cmp( step.signal ), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue