Sim Model Editor: Display model parameters
This commit adds parameter display functionality, via a wxPropertyGrid widget, to the Sim Model Editor. To faciliate that, a SIM_VALUE class is created to serialize, deserialize, and validate numeric values in the new parameter grid. SPICE_MODEL is renamed to SIM_MODEL and split into several subclasses that correspond to different model kinds.
This commit is contained in:
parent
229e5c9e0f
commit
c5a256291e
|
@ -319,8 +319,16 @@ if( KICAD_SPICE )
|
|||
sim/sim_plot_frame_base.cpp
|
||||
sim/sim_plot_panel.cpp
|
||||
sim/sim_workbook.cpp
|
||||
sim/sim_model.cpp
|
||||
sim/sim_model_behavioral.cpp
|
||||
sim/sim_model_codemodel.cpp
|
||||
sim/sim_model_ideal.cpp
|
||||
sim/sim_model_ngspice.cpp
|
||||
sim/sim_model_rawspice.cpp
|
||||
sim/sim_model_source.cpp
|
||||
sim/sim_model_subcircuit.cpp
|
||||
sim/sim_value.cpp
|
||||
sim/spice_simulator.cpp
|
||||
sim/spice_model.cpp
|
||||
sim/spice_value.cpp
|
||||
widgets/tuner_slider.cpp
|
||||
widgets/tuner_slider_base.cpp
|
||||
|
|
|
@ -609,7 +609,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnEditSpiceModel( wxCommandEvent& event )
|
|||
int diff = m_fields->size();
|
||||
auto symbol = SCH_SYMBOL( *m_libEntry, m_libEntry->GetLibId(), nullptr, 0 );
|
||||
|
||||
DIALOG_SPICE_MODEL dialog( this, symbol, m_fields );
|
||||
DIALOG_SPICE_MODEL dialog( this, symbol, *m_fields );
|
||||
|
||||
if( dialog.ShowModal() != wxID_OK )
|
||||
return;
|
||||
|
|
|
@ -26,32 +26,36 @@
|
|||
#include <dialog_spice_model.h>
|
||||
#include <confirm.h>
|
||||
|
||||
using TYPE = SIM_VALUE_BASE::TYPE;
|
||||
using CATEGORY = SIM_MODEL::PARAM::CATEGORY;
|
||||
|
||||
|
||||
template class DIALOG_SPICE_MODEL<SCH_FIELD>;
|
||||
template class DIALOG_SPICE_MODEL<LIB_FIELD>;
|
||||
|
||||
template <typename T>
|
||||
DIALOG_SPICE_MODEL<T>::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
|
||||
std::vector<T>* aFields )
|
||||
std::vector<T>& aFields )
|
||||
: DIALOG_SPICE_MODEL_BASE( aParent ),
|
||||
m_symbol( aSymbol ),
|
||||
m_fields( aFields )
|
||||
m_fields( aFields ),
|
||||
m_firstCategory( nullptr )
|
||||
{
|
||||
try
|
||||
{
|
||||
SPICE_MODEL::TYPE typeFromFields = SPICE_MODEL::ReadTypeFromFields( aFields );
|
||||
SIM_MODEL::TYPE typeFromFields = SIM_MODEL::ReadTypeFromFields( aFields );
|
||||
|
||||
for( SPICE_MODEL::TYPE type : SPICE_MODEL::TYPE_ITERATOR() )
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
{
|
||||
if( type == typeFromFields )
|
||||
{
|
||||
m_models.emplace_back( aFields );
|
||||
m_models.push_back( SIM_MODEL::Create( aFields ) );
|
||||
m_curModelType = type;
|
||||
}
|
||||
else
|
||||
m_models.emplace_back( type );
|
||||
m_models.push_back( SIM_MODEL::Create( type ) );
|
||||
|
||||
SPICE_MODEL::DEVICE_TYPE deviceType = SPICE_MODEL::TypeInfo( type ).deviceType;
|
||||
SIM_MODEL::DEVICE_TYPE deviceType = SIM_MODEL::TypeInfo( type ).deviceType;
|
||||
|
||||
// By default choose the first model type of each device type.
|
||||
if( !m_curModelTypeOfDeviceType.count( deviceType ) )
|
||||
|
@ -67,8 +71,11 @@ DIALOG_SPICE_MODEL<T>::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbo
|
|||
|
||||
m_typeChoice->Clear();
|
||||
|
||||
for( SPICE_MODEL::DEVICE_TYPE deviceType : SPICE_MODEL::DEVICE_TYPE_ITERATOR() )
|
||||
m_deviceTypeChoice->Append( SPICE_MODEL::DeviceTypeInfo( deviceType ).description );
|
||||
for( SIM_MODEL::DEVICE_TYPE deviceType : SIM_MODEL::DEVICE_TYPE_ITERATOR() )
|
||||
m_deviceTypeChoice->Append( SIM_MODEL::DeviceTypeInfo( deviceType ).description );
|
||||
|
||||
m_paramGrid = m_paramGridMgr->AddPage();
|
||||
|
||||
|
||||
m_scintillaTricks = std::make_unique<SCINTILLA_TRICKS>( m_codePreview, wxT( "{}" ), false );
|
||||
|
||||
|
@ -82,7 +89,7 @@ bool DIALOG_SPICE_MODEL<T>::TransferDataFromWindow()
|
|||
if( !DIALOG_SPICE_MODEL_BASE::TransferDataFromWindow() )
|
||||
return false;
|
||||
|
||||
m_models[static_cast<int>( m_curModelType )].WriteFields( m_fields );
|
||||
m_models[static_cast<int>( m_curModelType )]->WriteFields( m_fields );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -93,8 +100,8 @@ bool DIALOG_SPICE_MODEL<T>::TransferDataToWindow()
|
|||
{
|
||||
try
|
||||
{
|
||||
m_models[static_cast<int>( SPICE_MODEL::ReadTypeFromFields( m_fields ) )]
|
||||
= SPICE_MODEL( m_fields );
|
||||
m_models[static_cast<int>( SIM_MODEL::ReadTypeFromFields( m_fields ) )]
|
||||
= SIM_MODEL::Create( m_fields );
|
||||
}
|
||||
catch( KI_PARAM_ERROR& e )
|
||||
{
|
||||
|
@ -111,17 +118,17 @@ bool DIALOG_SPICE_MODEL<T>::TransferDataToWindow()
|
|||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::updateWidgets()
|
||||
{
|
||||
SPICE_MODEL::DEVICE_TYPE deviceType = SPICE_MODEL::TypeInfo( m_curModelType ).deviceType;
|
||||
SIM_MODEL::DEVICE_TYPE deviceType = SIM_MODEL::TypeInfo( m_curModelType ).deviceType;
|
||||
|
||||
m_deviceTypeChoice->SetSelection( static_cast<int>( deviceType ) );
|
||||
|
||||
m_typeChoice->Clear();
|
||||
|
||||
for( SPICE_MODEL::TYPE type : SPICE_MODEL::TYPE_ITERATOR() )
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
{
|
||||
if( SPICE_MODEL::TypeInfo( type ).deviceType == deviceType )
|
||||
if( SIM_MODEL::TypeInfo( type ).deviceType == deviceType )
|
||||
{
|
||||
wxString description = SPICE_MODEL::TypeInfo( type ).description;
|
||||
wxString description = SIM_MODEL::TypeInfo( type ).description;
|
||||
|
||||
if( !description.IsEmpty() )
|
||||
m_typeChoice->Append( description );
|
||||
|
@ -131,34 +138,60 @@ void DIALOG_SPICE_MODEL<T>::updateWidgets()
|
|||
}
|
||||
}
|
||||
|
||||
//m_typeChoice->SetSelection( static_cast<int>( m_curModelType ) );
|
||||
|
||||
m_paramGrid->ClearRows();
|
||||
// This wxPropertyGridManager stuff has to be here because it segfaults in the constructor.
|
||||
|
||||
//if( m_model.Get
|
||||
m_paramGridMgr->SetColumnCount( static_cast<int>( COLUMN::END_ ) );
|
||||
|
||||
/*if( m_model.GetSubtype() != SPICE_MODEL::SUBTYPE::NONE )
|
||||
{
|
||||
m_paramGrid->AppendRows( 1 );
|
||||
m_paramGridMgr->SetColumnTitle( static_cast<int>( COLUMN::UNIT ), "Unit" );
|
||||
m_paramGridMgr->SetColumnTitle( static_cast<int>( COLUMN::DEFAULT ), "Default" );
|
||||
m_paramGridMgr->SetColumnTitle( static_cast<int>( COLUMN::TYPE ), "Type" );
|
||||
|
||||
m_paramGrid->SetReadOnly( 0, COLUMN::DESCRIPTION );
|
||||
m_paramGrid->SetReadOnly( 0, COLUMN::NAME );
|
||||
m_paramGrid->SetReadOnly( 0, COLUMN::UNIT );
|
||||
m_paramGridMgr->ShowHeader();
|
||||
|
||||
m_paramGrid->SetCellValue( 0, COLUMN::VALUE,
|
||||
SPICE_MODEL::SubtypeInfo( m_model.GetSubtype() ).description );
|
||||
}*/
|
||||
|
||||
m_paramGrid->Clear();
|
||||
|
||||
m_firstCategory = m_paramGrid->Append( new wxPropertyCategory( "DC" ) );
|
||||
m_paramGrid->HideProperty( "DC" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Temperature" ) );
|
||||
m_paramGrid->HideProperty( "Temperature" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Noise" ) );
|
||||
m_paramGrid->HideProperty( "Noise" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Distributed Quantities" ) );
|
||||
m_paramGrid->HideProperty( "Distributed Quantities" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Geometry" ) );
|
||||
m_paramGrid->HideProperty( "Geometry" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Limiting Values" ) );
|
||||
m_paramGrid->HideProperty( "Limiting Values" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Advanced" ) );
|
||||
m_paramGrid->HideProperty( "Advanced" );
|
||||
|
||||
m_paramGrid->Append( new wxPropertyCategory( "Flags" ) );
|
||||
m_paramGrid->HideProperty( "Flags" );
|
||||
|
||||
SIM_MODEL& curModel = *m_models[static_cast<int>( m_curModelType )];
|
||||
|
||||
for( const SIM_MODEL::PARAM& param : curModel.Params() )
|
||||
addParamPropertyIfRelevant( param );
|
||||
|
||||
m_paramGrid->CollapseAll();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent )
|
||||
{
|
||||
//SPICE_MODEL::DEVICE_TYPE deviceType = SPICE_MODEL::TypeInfo( m_curModelType ).deviceType;
|
||||
SPICE_MODEL::DEVICE_TYPE deviceType =
|
||||
static_cast<SPICE_MODEL::DEVICE_TYPE>( m_deviceTypeChoice->GetSelection() );
|
||||
SIM_MODEL::DEVICE_TYPE deviceType =
|
||||
static_cast<SIM_MODEL::DEVICE_TYPE>( m_deviceTypeChoice->GetSelection() );
|
||||
|
||||
m_curModelType = m_curModelTypeOfDeviceType[deviceType];
|
||||
m_curModelType = m_curModelTypeOfDeviceType.at( deviceType );
|
||||
|
||||
updateWidgets();
|
||||
}
|
||||
|
@ -167,28 +200,142 @@ void DIALOG_SPICE_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent )
|
|||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
|
||||
{
|
||||
SPICE_MODEL::DEVICE_TYPE deviceType =
|
||||
static_cast<SPICE_MODEL::DEVICE_TYPE>( m_deviceTypeChoice->GetSelection() );
|
||||
SIM_MODEL::DEVICE_TYPE deviceType =
|
||||
static_cast<SIM_MODEL::DEVICE_TYPE>( m_deviceTypeChoice->GetSelection() );
|
||||
wxString typeDescription = m_typeChoice->GetString( m_typeChoice->GetSelection() );
|
||||
|
||||
for( SPICE_MODEL::TYPE type : SPICE_MODEL::TYPE_ITERATOR() )
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
{
|
||||
if( deviceType == SPICE_MODEL::TypeInfo( type ).deviceType
|
||||
&& typeDescription == SPICE_MODEL::TypeInfo( type ).description )
|
||||
if( deviceType == SIM_MODEL::TypeInfo( type ).deviceType
|
||||
&& typeDescription == SIM_MODEL::TypeInfo( type ).description )
|
||||
{
|
||||
m_curModelType = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_curModelTypeOfDeviceType[deviceType] = m_curModelType;
|
||||
m_curModelTypeOfDeviceType.at( deviceType ) = m_curModelType;
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SPICE_MODEL<T>::onGridCellChange( wxGridEvent& aEvent )
|
||||
void DIALOG_SPICE_MODEL<T>::addParamPropertyIfRelevant( const SIM_MODEL::PARAM& aParam )
|
||||
{
|
||||
/*updateModel();
|
||||
updateWidgets();*/
|
||||
if( aParam.info.dir == SIM_MODEL::PARAM::DIR::OUT )
|
||||
return;
|
||||
|
||||
switch( aParam.info.category )
|
||||
{
|
||||
case CATEGORY::DC:
|
||||
m_paramGrid->HideProperty( "DC", false );
|
||||
m_paramGrid->AppendIn( "DC", newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::CAPACITANCE:
|
||||
m_paramGrid->HideProperty( "Capacitance", false );
|
||||
m_paramGrid->AppendIn( "Capacitance", newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::TEMPERATURE:
|
||||
m_paramGrid->HideProperty( "Temperature", false );
|
||||
m_paramGrid->AppendIn( "Temperature", newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::NOISE:
|
||||
m_paramGrid->HideProperty( "Noise", false );
|
||||
m_paramGrid->AppendIn( "Noise", newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::DISTRIBUTED_QUANTITIES:
|
||||
m_paramGrid->HideProperty( "Distributed Quantities", false );
|
||||
m_paramGrid->AppendIn( "Distributed Quantities", newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::GEOMETRY:
|
||||
m_paramGrid->HideProperty( "Geometry", false );
|
||||
m_paramGrid->AppendIn( "Geometry", newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::LIMITING_VALUES:
|
||||
m_paramGrid->HideProperty( "Limiting Values", false );
|
||||
m_paramGrid->AppendIn( "Limiting Values", newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::ADVANCED:
|
||||
m_paramGrid->HideProperty( "Advanced", false );
|
||||
m_paramGrid->AppendIn( "Advanced", newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::FLAGS:
|
||||
m_paramGrid->HideProperty( "Flags", false );
|
||||
m_paramGrid->AppendIn( "Flags", newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
//m_paramGrid->AppendIn( nullptr, newParamProperty( aParam ) );
|
||||
m_paramGrid->Insert( m_firstCategory, newParamProperty( aParam ) );
|
||||
//m_paramGrid->Append( newParamProperty( aParam ) );
|
||||
break;
|
||||
|
||||
case CATEGORY::INITIAL_CONDITIONS:
|
||||
case CATEGORY::SUPERFLUOUS:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
wxPGProperty* DIALOG_SPICE_MODEL<T>::newParamProperty( const SIM_MODEL::PARAM& aParam ) const
|
||||
{
|
||||
wxString paramDescription = wxString::Format( "%s (%s)",
|
||||
aParam.info.description,
|
||||
aParam.info.name );
|
||||
wxPGProperty* prop = nullptr;
|
||||
|
||||
switch( aParam.info.type )
|
||||
{
|
||||
case TYPE::INT:
|
||||
prop = new wxIntProperty( paramDescription );
|
||||
break;
|
||||
|
||||
case TYPE::FLOAT:
|
||||
prop = new wxFloatProperty( paramDescription );
|
||||
break;
|
||||
|
||||
case TYPE::BOOL:
|
||||
prop = new wxBoolProperty( paramDescription );
|
||||
prop->SetAttribute( wxPG_BOOL_USE_CHECKBOX, true );
|
||||
break;
|
||||
|
||||
default:
|
||||
prop = new wxStringProperty( paramDescription );
|
||||
break;
|
||||
}
|
||||
|
||||
prop->SetAttribute( wxPG_ATTR_UNITS, aParam.info.unit );
|
||||
|
||||
// Legacy due to the way we extracted parameters from Ngspice.
|
||||
if( aParam.isOtherVariant )
|
||||
prop->SetCell( 3, aParam.info.defaultValueOfOtherVariant );
|
||||
else
|
||||
prop->SetCell( 3, aParam.info.defaultValue );
|
||||
|
||||
wxString typeStr;
|
||||
|
||||
switch( aParam.info.type )
|
||||
{
|
||||
case TYPE::BOOL: typeStr = wxString( "Bool" ); break;
|
||||
case TYPE::INT: typeStr = wxString( "Integer" ); break;
|
||||
case TYPE::FLOAT: typeStr = wxString( "Float" ); break;
|
||||
case TYPE::COMPLEX: typeStr = wxString( "Complex" ); break;
|
||||
case TYPE::STRING: typeStr = wxString( "String" ); break;
|
||||
case TYPE::BOOL_VECTOR: typeStr = wxString( "Bool Vector" ); break;
|
||||
case TYPE::INT_VECTOR: typeStr = wxString( "Int Vector" ); break;
|
||||
case TYPE::FLOAT_VECTOR: typeStr = wxString( "Float Vector" ); break;
|
||||
case TYPE::COMPLEX_VECTOR: typeStr = wxString( "Complex Vector" ); break;
|
||||
}
|
||||
|
||||
prop->SetCell( static_cast<int>( COLUMN::TYPE ), typeStr );
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
|
|
@ -29,17 +29,21 @@
|
|||
#include <netlist_exporter_pspice.h>
|
||||
#include <scintilla_tricks.h>
|
||||
|
||||
#include <sim/spice_model.h>
|
||||
#include <sim/sim_model.h>
|
||||
#include <sch_symbol.h>
|
||||
|
||||
// Some probable wxWidgets bugs encountered when writing this class:
|
||||
// 1. There are rendering problems with wxPropertyGrid on Linux, GTK, Xorg when
|
||||
// wxPG_NATIVE_DOUBLE_BUFFERING flag is not set.
|
||||
// 2. wxPropertyGridManager->ShowHeader() segfaults when called from this dialog's constructor.
|
||||
|
||||
template <typename T>
|
||||
class DIALOG_SPICE_MODEL : public DIALOG_SPICE_MODEL_BASE
|
||||
{
|
||||
public:
|
||||
enum COLUMN { DESCRIPTION, NAME, VALUE, UNIT };
|
||||
enum class COLUMN : int { DESCRIPTION = 0, VALUE, UNIT, DEFAULT, TYPE, END_ };
|
||||
|
||||
DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
|
||||
std::vector<T>* aSchFields );
|
||||
DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol, std::vector<T>& aSchFields );
|
||||
|
||||
private:
|
||||
bool TransferDataFromWindow() override;
|
||||
|
@ -50,15 +54,19 @@ private:
|
|||
|
||||
void onDeviceTypeChoice( wxCommandEvent& aEvent ) override;
|
||||
void onTypeChoice( wxCommandEvent& aEvent ) override;
|
||||
void onGridCellChange( wxGridEvent& aEvent ) override;
|
||||
|
||||
void addParamPropertyIfRelevant( const SIM_MODEL::PARAM& aParam );
|
||||
wxPGProperty* newParamProperty( const SIM_MODEL::PARAM& aParam ) const;
|
||||
|
||||
SCH_SYMBOL& m_symbol;
|
||||
std::vector<T>* m_fields;
|
||||
std::vector<T>& m_fields;
|
||||
|
||||
std::vector<SPICE_MODEL> m_models;
|
||||
std::map<SPICE_MODEL::DEVICE_TYPE, SPICE_MODEL::TYPE> m_curModelTypeOfDeviceType;
|
||||
SPICE_MODEL::TYPE m_curModelType = SPICE_MODEL::TYPE::NONE;
|
||||
std::vector<std::unique_ptr<SIM_MODEL>> m_models;
|
||||
std::map<SIM_MODEL::DEVICE_TYPE, SIM_MODEL::TYPE> m_curModelTypeOfDeviceType;
|
||||
SIM_MODEL::TYPE m_curModelType = SIM_MODEL::TYPE::NONE;
|
||||
|
||||
wxPropertyGridPage* m_paramGrid;
|
||||
wxPGProperty* m_firstCategory; // Used to add principal parameters to root (any better ideas?)
|
||||
std::unique_ptr<SCINTILLA_TRICKS> m_scintillaTricks;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -94,40 +94,9 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
|
|||
|
||||
bSizer12->Add( fgSizer16, 0, wxEXPAND, 5 );
|
||||
|
||||
m_paramGrid = new WX_GRID( m_parametersPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
||||
// Grid
|
||||
m_paramGrid->CreateGrid( 0, 4 );
|
||||
m_paramGrid->EnableEditing( true );
|
||||
m_paramGrid->EnableGridLines( true );
|
||||
m_paramGrid->EnableDragGridSize( false );
|
||||
m_paramGrid->SetMargins( 0, 0 );
|
||||
|
||||
// Columns
|
||||
m_paramGrid->SetColSize( 0, 300 );
|
||||
m_paramGrid->SetColSize( 1, 80 );
|
||||
m_paramGrid->SetColSize( 2, 80 );
|
||||
m_paramGrid->SetColSize( 3, 50 );
|
||||
m_paramGrid->EnableDragColMove( true );
|
||||
m_paramGrid->EnableDragColSize( true );
|
||||
m_paramGrid->SetColLabelValue( 0, wxT("Description") );
|
||||
m_paramGrid->SetColLabelValue( 1, wxT("Name") );
|
||||
m_paramGrid->SetColLabelValue( 2, wxT("Value") );
|
||||
m_paramGrid->SetColLabelValue( 3, wxT("Unit") );
|
||||
m_paramGrid->SetColLabelSize( 22 );
|
||||
m_paramGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
// Rows
|
||||
m_paramGrid->EnableDragRowSize( false );
|
||||
m_paramGrid->SetRowLabelSize( 0 );
|
||||
m_paramGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
// Label Appearance
|
||||
m_paramGrid->SetLabelFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
|
||||
|
||||
// Cell Defaults
|
||||
m_paramGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
|
||||
bSizer12->Add( m_paramGrid, 1, wxALL|wxEXPAND, 5 );
|
||||
m_paramGridMgr = new wxPropertyGridManager(m_parametersPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxPGMAN_DEFAULT_STYLE);
|
||||
m_paramGridMgr->SetExtraStyle( wxPG_EX_MODE_BUTTONS|wxPG_EX_NATIVE_DOUBLE_BUFFERING );
|
||||
bSizer12->Add( m_paramGridMgr, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_parametersPanel->SetSizer( bSizer12 );
|
||||
|
@ -251,14 +220,12 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
|
|||
|
||||
this->SetSizer( bSizer8 );
|
||||
this->Layout();
|
||||
bSizer8->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
|
||||
// Connect Events
|
||||
m_deviceTypeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoice ), NULL, this );
|
||||
m_typeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoice ), NULL, this );
|
||||
m_paramGrid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SPICE_MODEL_BASE::onGridCellChange ), NULL, this );
|
||||
}
|
||||
|
||||
DIALOG_SPICE_MODEL_BASE::~DIALOG_SPICE_MODEL_BASE()
|
||||
|
@ -266,6 +233,5 @@ DIALOG_SPICE_MODEL_BASE::~DIALOG_SPICE_MODEL_BASE()
|
|||
// Disconnect Events
|
||||
m_deviceTypeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoice ), NULL, this );
|
||||
m_typeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoice ), NULL, this );
|
||||
m_paramGrid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SPICE_MODEL_BASE::onGridCellChange ), NULL, this );
|
||||
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<property name="minimum_size"></property>
|
||||
<property name="name">DIALOG_SPICE_MODEL_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="size">600,800</property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="title">Spice Model Editor</property>
|
||||
|
@ -997,7 +997,7 @@
|
|||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxGrid" expanded="1">
|
||||
<object class="wxPropertyGridManager" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
|
@ -1006,50 +1006,27 @@
|
|||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="autosize_cols">0</property>
|
||||
<property name="autosize_rows">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="cell_bg"></property>
|
||||
<property name="cell_font"></property>
|
||||
<property name="cell_horiz_alignment">wxALIGN_LEFT</property>
|
||||
<property name="cell_text"></property>
|
||||
<property name="cell_vert_alignment">wxALIGN_TOP</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
|
||||
<property name="col_label_size">22</property>
|
||||
<property name="col_label_values">"Description" "Name" "Value" "Unit"</property>
|
||||
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
|
||||
<property name="cols">4</property>
|
||||
<property name="column_sizes">300,80,80,50</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="drag_col_move">1</property>
|
||||
<property name="drag_col_size">1</property>
|
||||
<property name="drag_grid_size">0</property>
|
||||
<property name="drag_row_size">0</property>
|
||||
<property name="editing">1</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="extra_style">wxPG_EX_MODE_BUTTONS|wxPG_EX_NATIVE_DOUBLE_BUFFERING</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="grid_line_color"></property>
|
||||
<property name="grid_lines">1</property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label_bg"></property>
|
||||
<property name="label_font">,90,92,-1,70,0</property>
|
||||
<property name="label_text"></property>
|
||||
<property name="margin_height">0</property>
|
||||
<property name="margin_width">0</property>
|
||||
<property name="include_advanced">1</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
|
@ -1057,7 +1034,7 @@
|
|||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_paramGrid</property>
|
||||
<property name="name">m_paramGridMgr</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
|
@ -1065,21 +1042,15 @@
|
|||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="row_label_horiz_alignment">wxALIGN_CENTER</property>
|
||||
<property name="row_label_size">0</property>
|
||||
<property name="row_label_values"></property>
|
||||
<property name="row_label_vert_alignment">wxALIGN_CENTER</property>
|
||||
<property name="row_sizes"></property>
|
||||
<property name="rows">0</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="subclass">WX_GRID; widgets/wx_grid.h; forward_declare</property>
|
||||
<property name="style">wxPGMAN_DEFAULT_STYLE</property>
|
||||
<property name="subclass">; ; forward_declare</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>
|
||||
<event name="OnGridCellChange">onGridCellChange</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -26,10 +26,13 @@ class WX_GRID;
|
|||
#include <wx/statbox.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/grid.h>
|
||||
#include <wx/propgrid/propgrid.h>
|
||||
#include <wx/propgrid/manager.h>
|
||||
#include <wx/propgrid/advprops.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/stc/stc.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/grid.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
|
@ -58,7 +61,7 @@ class DIALOG_SPICE_MODEL_BASE : public wxDialog
|
|||
wxChoice* m_deviceTypeChoice;
|
||||
wxStaticText* m_staticText8;
|
||||
wxChoice* m_typeChoice;
|
||||
WX_GRID* m_paramGrid;
|
||||
wxPropertyGridManager* m_paramGridMgr;
|
||||
wxPanel* m_codePanel;
|
||||
wxStyledTextCtrl* m_codePreview;
|
||||
wxPanel* m_pinAssignmentsPanel;
|
||||
|
@ -72,12 +75,11 @@ class DIALOG_SPICE_MODEL_BASE : public wxDialog
|
|||
// Virtual event handlers, override them in your derived class
|
||||
virtual void onDeviceTypeChoice( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onTypeChoice( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onGridCellChange( wxGridEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Spice Model Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP );
|
||||
DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Spice Model Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 600,800 ), long style = wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP );
|
||||
|
||||
~DIALOG_SPICE_MODEL_BASE();
|
||||
|
||||
|
|
|
@ -544,7 +544,7 @@ void DIALOG_SYMBOL_PROPERTIES::OnEditSpiceModel( wxCommandEvent& event )
|
|||
#ifdef KICAD_SPICE
|
||||
int diff = m_fields->size();
|
||||
|
||||
DIALOG_SPICE_MODEL dialog( this, *m_symbol, m_fields );
|
||||
DIALOG_SPICE_MODEL dialog( this, *m_symbol, *m_fields );
|
||||
|
||||
if( dialog.ShowModal() != wxID_OK )
|
||||
return;
|
||||
|
|
|
@ -1,371 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# This script is disgusting (very slow and hacky). Please rewrite it in Python if you have time.
|
||||
|
||||
|
||||
MODELS=$(cat << END
|
||||
resistor R - R 2 0 0
|
||||
capacitor C - C 2 0 0
|
||||
inductor L - L 2 0 0
|
||||
|
||||
ltra LTRA - O 4 0 0
|
||||
tranline - - T 4 0 0
|
||||
urc URC - U 3 0 0
|
||||
transline - - Y 4 0 0
|
||||
|
||||
diode D - D 2 0 0
|
||||
|
||||
bjt NPN PNP Q 3 1 0
|
||||
vbic NPN PNP Q 3 4 0
|
||||
hicum2 NPN PNP Q 3 8 0
|
||||
|
||||
jfet NJF PJF J 3 1 0
|
||||
jfet2 NJF PJF J 3 2 0
|
||||
|
||||
mes NMF PMF Z 3 1 0
|
||||
mesa NMF PMF Z 3 2 0
|
||||
hfet1 NMF PMF Z 3 5 0
|
||||
hfet2 NMF PMF Z 3 6 0
|
||||
|
||||
mos1 NMOS PMOS M 4 1 0
|
||||
mos2 NMOS PMOS M 4 2 0
|
||||
mos3 NMOS PMOS M 4 3 0
|
||||
bsim1 NMOS PMOS M 4 4 0
|
||||
bsim2 NMOS PMOS M 4 5 0
|
||||
mos6 NMOS PMOS M 4 6 0
|
||||
bsim3 NMOS PMOS M 4 8 3.3.0
|
||||
mos9 NMOS PMOS M 4 9 0
|
||||
b4soi NMOS PMOS M 4 10 0
|
||||
bsim4 NMOS PMOS M 4 14 4.8.1
|
||||
b3soifd NMOS PMOS M 4 55 0
|
||||
b3soidd NMOS PMOS M 4 56 0
|
||||
b3soipd NMOS PMOS M 4 57 0
|
||||
hisim2 NMOS PMOS M 4 68 0
|
||||
hisimhv1 NMOS PMOS M 4 73 1.2.4
|
||||
hisimhv2 NMOS PMOS M 4 73 2.2.0
|
||||
END
|
||||
)
|
||||
|
||||
|
||||
UNITS=$(cat << END
|
||||
%/deg C
|
||||
exponent alternative
|
||||
|
||||
-
|
||||
exponent
|
||||
|
||||
ohm/m
|
||||
sheet resistance
|
||||
resistance per unit length
|
||||
|
||||
ohm
|
||||
resistance
|
||||
resistor model default value
|
||||
|
||||
F/m^2
|
||||
cap per area
|
||||
|
||||
F/m
|
||||
capacitance per meter
|
||||
overlap cap
|
||||
capacitance per unit length
|
||||
capacitance grading coefficient per unit length
|
||||
|
||||
F
|
||||
capacitance
|
||||
cap\.
|
||||
|
||||
H
|
||||
inductance
|
||||
|
||||
1/W
|
||||
coef of thermal current reduction
|
||||
|
||||
sqrt V
|
||||
bulk effect coefficient 1
|
||||
bulk threshold parameter
|
||||
|
||||
1/V
|
||||
channel length modulation
|
||||
vgs dependence on mobility
|
||||
|
||||
V/cm
|
||||
Crit. field for mob. degradation
|
||||
|
||||
V
|
||||
voltage
|
||||
potential
|
||||
|
||||
A/V^2
|
||||
transconductance parameter
|
||||
|
||||
A/m^2
|
||||
current density
|
||||
|
||||
A/m
|
||||
current per unit length
|
||||
|
||||
A
|
||||
current
|
||||
|
||||
ohm/deg C^2
|
||||
second order temp. coefficient
|
||||
|
||||
ohm/deg C
|
||||
first order temp. coefficient
|
||||
|
||||
1/deg C^2
|
||||
grading coefficient 1st temp. coeff
|
||||
|
||||
1/deg C
|
||||
grading coefficient 2nd temp. coeff
|
||||
|
||||
deg C/W
|
||||
thermal resistance
|
||||
|
||||
deg C
|
||||
temperature
|
||||
|
||||
eV
|
||||
energy
|
||||
|
||||
cm^2/V^2 s
|
||||
VBS dependence on muz
|
||||
VBS dependence on mus
|
||||
VDS dependence on mus
|
||||
|
||||
cm^2/V s
|
||||
zero field mobility
|
||||
surface mobility
|
||||
|
||||
um/V^2
|
||||
VDS depence of u1
|
||||
|
||||
um
|
||||
.* in um
|
||||
|
||||
1/cm^3
|
||||
substrate doping
|
||||
|
||||
1/cm^2
|
||||
surface state density
|
||||
fast surface state density
|
||||
|
||||
m/s
|
||||
velocity
|
||||
|
||||
m
|
||||
length
|
||||
width
|
||||
thickness
|
||||
narrowing of
|
||||
shortening of
|
||||
|
||||
C
|
||||
epi charge parameter
|
||||
|
||||
s
|
||||
time
|
||||
|
||||
deg
|
||||
excess phase
|
||||
|
||||
-
|
||||
.*
|
||||
END
|
||||
)
|
||||
|
||||
|
||||
run_ngspice()
|
||||
{
|
||||
ngspice -n 2>/dev/null << END
|
||||
*
|
||||
$1
|
||||
.control
|
||||
$2
|
||||
.endc
|
||||
END
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
echo "// Generated using the $(basename $0) script."
|
||||
echo "// Modify that script instead of this file if you want to make changes."
|
||||
echo ""
|
||||
echo "#include <sim/ngspice.h>"
|
||||
echo ""
|
||||
|
||||
echo "enum class NGSPICE::MODEL_TYPE"
|
||||
echo "{"
|
||||
|
||||
echo "$MODELS" | while read -r model_name model_primitive model_level model_version; do
|
||||
if [ -n "$model_name" ]; then
|
||||
echo " ${model_name^^},"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "};"
|
||||
echo ""
|
||||
|
||||
echo "NGSPICE::MODEL_INFO NGSPICE::GetModelInfo( NGSPICE::MODEL_TYPE aType )"
|
||||
echo "{"
|
||||
echo " switch( aType )"
|
||||
echo " {"
|
||||
|
||||
echo "$MODELS" | while read -r model_name \
|
||||
model_type1 \
|
||||
model_type2 \
|
||||
model_primitive \
|
||||
model_pin_count \
|
||||
model_level \
|
||||
model_version
|
||||
do
|
||||
if [ -n "$model_name" ]; then
|
||||
# Print model description.
|
||||
run_ngspice "" "devhelp -type $model_name" | while read -r name sep description; do
|
||||
if [ "$sep" = "-" ]; then
|
||||
echo -n " case NGSPICE::MODEL_TYPE::${model_name^^}:"
|
||||
echo -n " return { \"$name\","
|
||||
|
||||
for model_type in "$model_type1" "$model_type2"; do
|
||||
if [ "$model_type" != "-" ]; then
|
||||
echo -n " \"$model_type\","
|
||||
else
|
||||
echo -n " \"\","
|
||||
fi
|
||||
done
|
||||
|
||||
echo " \"$description\","
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
# Print model parameter ID, name, direction, type, unit, and description.
|
||||
run_ngspice "" "devhelp -type $model_name" | while read -r param_id \
|
||||
param_name \
|
||||
param_dir \
|
||||
param_type \
|
||||
param_description
|
||||
do
|
||||
if [ "$param_id" = "Model" ] && [ "$param_name" = "Parameters" ]; then
|
||||
echo " // Model parameters"
|
||||
echo " {"
|
||||
elif [ "$param_id" = "Instance" ] && [ "$param_name" = "Parameters" ]; then
|
||||
echo " },"
|
||||
echo " // Instance parameters"
|
||||
echo " {"
|
||||
elif [ "$param_id" -eq "$param_id" ] 2>/dev/null \
|
||||
&& [ -n "$param_name" ] \
|
||||
&& [ -n "$param_dir" ] \
|
||||
&& [ -n "$param_description" ]
|
||||
then
|
||||
echo -n " { \"${param_name,,}\","
|
||||
echo -n " { $param_id,"
|
||||
echo -n " NGSPICE::PARAM_DIR::${param_dir^^},"
|
||||
echo -n " NGSPICE::PARAM_TYPE::${param_type^^},"
|
||||
|
||||
|
||||
unit=""
|
||||
|
||||
# Non-reals are unlikely to have units.
|
||||
if [ "$param_type" = "real" ]; then
|
||||
# Don't use a pipe here because it creates a subshell, as it prevents the
|
||||
# changes to the variables from propagating upwards. Bash is cursed.
|
||||
while read -r pattern; do
|
||||
if [ "$unit" = "" ]; then
|
||||
unit="$pattern"
|
||||
elif [ -z "$pattern" ]; then
|
||||
unit=""
|
||||
elif grep -iE "$pattern" <<< "$param_description" >/dev/null; then
|
||||
break
|
||||
fi
|
||||
done <<< "$UNITS"
|
||||
fi
|
||||
|
||||
if [ "$unit" = "-" ]; then
|
||||
unit=""
|
||||
fi
|
||||
|
||||
echo -n " \"$unit\","
|
||||
|
||||
for model_type in "$model_type1" "$model_type2"; do
|
||||
if [ "$model_type" = "-" ]; then
|
||||
echo -n " \"\","
|
||||
continue
|
||||
fi
|
||||
|
||||
# For a given primitive, Ngspice determines the device model to be used
|
||||
# from two parameters: "level" and "version".
|
||||
params=""
|
||||
|
||||
if [ "$model_level" != 0 ]; then
|
||||
params="$params level=$model_level"
|
||||
fi
|
||||
|
||||
if [ "$model_version" != 0 ]; then
|
||||
params="$params version=$model_version"
|
||||
fi
|
||||
|
||||
netlist=$(cat << END
|
||||
.model $model_type $model_type($params)
|
||||
${model_primitive}1 $(seq -s ' ' $model_pin_count) $model_type
|
||||
END
|
||||
)
|
||||
|
||||
control=$(cat << END
|
||||
op
|
||||
showmod ${model_primitive}1 : $param_name
|
||||
END
|
||||
)
|
||||
|
||||
was_model_line=0
|
||||
was_echoed=0
|
||||
|
||||
# Don't use a pipe here either.
|
||||
while read -r name value; do
|
||||
# Ngspice displays only the first 11 characters of the variable name.
|
||||
# We also convert to lowercase because a few parameter names have
|
||||
# uppercase characters in them.
|
||||
|
||||
lowercase_name=${name,,}
|
||||
lowercase_param_name=${param_name,,}
|
||||
|
||||
if [ "$was_model_line" = 0 ] && [ "$lowercase_name" = "model" ]; then
|
||||
was_model_line=1
|
||||
elif [ "$was_model_line" = 1 ] \
|
||||
&& [ "$lowercase_name" = "${lowercase_param_name:0:11}" ]
|
||||
then
|
||||
if [ "$value" = "<<NAN, error = 7>>" ]; then
|
||||
value="NaN"
|
||||
elif [ "$value" = "?????????" ]; then
|
||||
value=""
|
||||
fi
|
||||
|
||||
was_echoed=1
|
||||
echo -n " \"$value\","
|
||||
fi
|
||||
done < <(run_ngspice "$netlist" "$control")
|
||||
|
||||
if [ "$was_echoed" = 0 ]; then
|
||||
echo ""
|
||||
echo "Error! Default value not found."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo " \"$param_description\" } },"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
echo " } };"
|
||||
fi
|
||||
done
|
||||
|
||||
echo " }"
|
||||
echo ""
|
||||
|
||||
echo " wxFAIL;"
|
||||
echo " return {};"
|
||||
echo "}"
|
||||
} > $(dirname "$0")/ngspice_models.cpp
|
|
@ -27,10 +27,13 @@
|
|||
#ifndef NGSPICE_H
|
||||
#define NGSPICE_H
|
||||
|
||||
#include "spice_simulator.h"
|
||||
#include <sim/spice_simulator.h>
|
||||
#include <sim/sim_model.h>
|
||||
#include <sim/sim_value.h>
|
||||
|
||||
#include <wx/dynlib.h>
|
||||
#include <ngspice/sharedspice.h>
|
||||
#include <enum_vector.h>
|
||||
|
||||
// We have an issue here where NGSPICE incorrectly used bool for years
|
||||
// and defined it to be int when in C-mode. We cannot adjust the function
|
||||
|
@ -47,56 +50,59 @@ class wxDynamicLibrary;
|
|||
class NGSPICE : public SPICE_SIMULATOR
|
||||
{
|
||||
public:
|
||||
enum class PARAM_DIR
|
||||
{
|
||||
IN,
|
||||
OUT,
|
||||
INOUT
|
||||
};
|
||||
|
||||
enum class PARAM_TYPE
|
||||
{
|
||||
FLAG,
|
||||
INTEGER,
|
||||
REAL,
|
||||
COMPLEX,
|
||||
NODE,
|
||||
INSTANCE,
|
||||
STRING,
|
||||
PARSETREE,
|
||||
VECTOR,
|
||||
FLAGVEC,
|
||||
INTVEC,
|
||||
REALVEC,
|
||||
CPLXVEC,
|
||||
NODEVEC,
|
||||
INSTVEC,
|
||||
STRINGVEC
|
||||
};
|
||||
|
||||
struct PARAM_INFO
|
||||
{
|
||||
unsigned int id;
|
||||
PARAM_DIR dir;
|
||||
PARAM_TYPE type;
|
||||
wxString unit;
|
||||
wxString defaultValueOfVariant1;
|
||||
wxString defaultValueOfVariant2;
|
||||
wxString description;
|
||||
};
|
||||
|
||||
enum class MODEL_TYPE; // Defined in ngspice_devices.cpp.
|
||||
DEFINE_ENUM_CLASS_WITH_ITERATOR( MODEL_TYPE,
|
||||
NONE,
|
||||
RESISTOR,
|
||||
CAPACITOR,
|
||||
INDUCTOR,
|
||||
LTRA,
|
||||
TRANLINE,
|
||||
URC,
|
||||
TRANSLINE,
|
||||
SWITCH,
|
||||
CSWITCH,
|
||||
DIODE,
|
||||
BJT,
|
||||
VBIC,
|
||||
HICUM2,
|
||||
JFET,
|
||||
JFET2,
|
||||
MES,
|
||||
MESA,
|
||||
HFET1,
|
||||
HFET2,
|
||||
MOS1,
|
||||
MOS2,
|
||||
MOS3,
|
||||
BSIM1,
|
||||
BSIM2,
|
||||
MOS6,
|
||||
BSIM3,
|
||||
MOS9,
|
||||
B4SOI,
|
||||
BSIM4,
|
||||
B3SOIFD,
|
||||
B3SOIDD,
|
||||
B3SOIPD,
|
||||
HISIM2,
|
||||
HISIMHV1,
|
||||
HISIMHV2
|
||||
)
|
||||
|
||||
// May be moved to the SPICE_MODEL class later.
|
||||
struct MODEL_INFO
|
||||
{
|
||||
wxString name;
|
||||
wxString variant1;
|
||||
wxString variant2;
|
||||
wxString description;
|
||||
std::map<wxString, PARAM_INFO> modelParams;
|
||||
std::map<wxString, PARAM_INFO> instanceParams;
|
||||
std::vector<SIM_MODEL::PARAM::INFO> modelParams;
|
||||
std::vector<SIM_MODEL::PARAM::INFO> instanceParams;
|
||||
};
|
||||
|
||||
|
||||
static const MODEL_INFO& ModelInfo( MODEL_TYPE aType );
|
||||
|
||||
NGSPICE();
|
||||
virtual ~NGSPICE();
|
||||
|
||||
|
@ -142,8 +148,6 @@ public:
|
|||
///< @copydoc SPICE_SIMULATOR::GetPhasePlot()
|
||||
std::vector<double> GetPhasePlot( const std::string& aName, int aMaxLen = -1 ) override final;
|
||||
|
||||
MODEL_INFO GetModelInfo( MODEL_TYPE aDeviceType );
|
||||
|
||||
std::vector<std::string> GetSettingCommands() const override final;
|
||||
|
||||
///< @copydoc SPICE_SIMULATOR::GetNetlist()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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_MODEL_H
|
||||
#define SIM_MODEL_H
|
||||
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <enum_vector.h>
|
||||
#include <sch_field.h>
|
||||
#include <lib_field.h>
|
||||
#include <sim/sim_value.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
|
||||
class SIM_MODEL
|
||||
{
|
||||
public:
|
||||
static constexpr auto DEVICE_TYPE_FIELD = "Model_Device";
|
||||
static constexpr auto TYPE_FIELD = "Model_Type";
|
||||
static constexpr auto FILE_FIELD = "Model_File";
|
||||
static constexpr auto PARAMS_FIELD = "Model_Params";
|
||||
|
||||
|
||||
DEFINE_ENUM_CLASS_WITH_ITERATOR( DEVICE_TYPE,
|
||||
NONE,
|
||||
|
||||
RESISTOR,
|
||||
CAPACITOR,
|
||||
INDUCTOR,
|
||||
TLINE,
|
||||
SWITCH,
|
||||
|
||||
DIODE,
|
||||
NPN,
|
||||
PNP,
|
||||
|
||||
NJF,
|
||||
PJF,
|
||||
|
||||
NMES,
|
||||
PMES,
|
||||
NMOS,
|
||||
PMOS,
|
||||
|
||||
VSOURCE,
|
||||
ISOURCE,
|
||||
|
||||
SUBCIRCUIT,
|
||||
CODEMODEL,
|
||||
RAWSPICE
|
||||
)
|
||||
|
||||
struct DEVICE_INFO
|
||||
{
|
||||
wxString fieldValue;
|
||||
wxString description;
|
||||
};
|
||||
|
||||
|
||||
DEFINE_ENUM_CLASS_WITH_ITERATOR( TYPE,
|
||||
NONE,
|
||||
|
||||
RESISTOR_IDEAL,
|
||||
RESISTOR_ADVANCED,
|
||||
RESISTOR_BEHAVIORAL,
|
||||
|
||||
CAPACITOR_IDEAL,
|
||||
CAPACITOR_ADVANCED,
|
||||
CAPACITOR_BEHAVIORAL,
|
||||
|
||||
INDUCTOR_IDEAL,
|
||||
INDUCTOR_ADVANCED,
|
||||
INDUCTOR_BEHAVIORAL,
|
||||
|
||||
TLINE_LOSSY,
|
||||
TLINE_LOSSLESS,
|
||||
TLINE_UNIFORM_RC,
|
||||
TLINE_KSPICE,
|
||||
|
||||
SWITCH_VCTRL,
|
||||
SWITCH_ICTRL,
|
||||
|
||||
DIODE,
|
||||
|
||||
NPN_GUMMEL_POON,
|
||||
PNP_GUMMEL_POON,
|
||||
NPN_VBIC,
|
||||
PNP_VBIC,
|
||||
//NPN_MEXTRAM,
|
||||
//PNP_MEXTRAM,
|
||||
NPN_HICUM_L2,
|
||||
PNP_HICUM_L2,
|
||||
//NPN_HICUM_L0,
|
||||
//PNP_HICUM_L0,
|
||||
|
||||
NJF_SHICHMAN_HODGES,
|
||||
PJF_SHICHMAN_HODGES,
|
||||
|
||||
NJF_PARKER_SKELLERN,
|
||||
PJF_PARKER_SKELLERN,
|
||||
|
||||
|
||||
NMES_STATZ,
|
||||
PMES_STATZ,
|
||||
|
||||
NMES_YTTERDAL,
|
||||
PMES_YTTERDAL,
|
||||
|
||||
NMES_HFET1,
|
||||
PMES_HFET1,
|
||||
|
||||
NMES_HFET2,
|
||||
PMES_HFET2,
|
||||
|
||||
|
||||
NMOS_MOS1,
|
||||
PMOS_MOS1,
|
||||
|
||||
NMOS_MOS2,
|
||||
PMOS_MOS2,
|
||||
|
||||
NMOS_MOS3,
|
||||
PMOS_MOS3,
|
||||
|
||||
NMOS_BSIM1,
|
||||
PMOS_BSIM1,
|
||||
|
||||
NMOS_BSIM2,
|
||||
PMOS_BSIM2,
|
||||
|
||||
NMOS_MOS6,
|
||||
PMOS_MOS6,
|
||||
|
||||
NMOS_MOS9,
|
||||
PMOS_MOS9,
|
||||
|
||||
NMOS_BSIM3,
|
||||
PMOS_BSIM3,
|
||||
|
||||
NMOS_B4SOI,
|
||||
PMOS_B4SOI,
|
||||
|
||||
NMOS_BSIM4,
|
||||
PMOS_BSIM4,
|
||||
|
||||
//NMOS_EKV2_6,
|
||||
//PMOS_EKV2_6,
|
||||
|
||||
//NMOS_PSP,
|
||||
//PMOS_PSP,
|
||||
|
||||
NMOS_B3SOIFD,
|
||||
PMOS_B3SOIFD,
|
||||
|
||||
NMOS_B3SOIDD,
|
||||
PMOS_B3SOIDD,
|
||||
|
||||
NMOS_B3SOIPD,
|
||||
PMOS_B3SOIPD,
|
||||
|
||||
//NMOS_STAG,
|
||||
//PMOS_STAG,
|
||||
|
||||
NMOS_HISIM2,
|
||||
PMOS_HISIM2,
|
||||
|
||||
NMOS_HISIM_HV1,
|
||||
PMOS_HISIM_HV1,
|
||||
|
||||
NMOS_HISIM_HV2,
|
||||
PMOS_HISIM_HV2,
|
||||
|
||||
|
||||
VSOURCE_PULSE,
|
||||
VSOURCE_SIN,
|
||||
VSOURCE_EXP,
|
||||
VSOURCE_SFAM,
|
||||
VSOURCE_SFFM,
|
||||
VSOURCE_PWL,
|
||||
VSOURCE_WHITE_NOISE,
|
||||
VSOURCE_PINK_NOISE,
|
||||
VSOURCE_BURST_NOISE,
|
||||
VSOURCE_RANDOM_UNIFORM,
|
||||
VSOURCE_RANDOM_NORMAL,
|
||||
VSOURCE_RANDOM_EXP,
|
||||
VSOURCE_RANDOM_POISSON,
|
||||
VSOURCE_BEHAVIORAL,
|
||||
|
||||
ISOURCE_PULSE,
|
||||
ISOURCE_SIN,
|
||||
ISOURCE_EXP,
|
||||
ISOURCE_SFAM,
|
||||
ISOURCE_SFFM,
|
||||
ISOURCE_PWL,
|
||||
ISOURCE_WHITE_NOISE,
|
||||
ISOURCE_PINK_NOISE,
|
||||
ISOURCE_BURST_NOISE,
|
||||
ISOURCE_RANDOM_UNIFORM,
|
||||
ISOURCE_RANDOM_NORMAL,
|
||||
ISOURCE_RANDOM_EXP,
|
||||
ISOURCE_RANDOM_POISSON,
|
||||
ISOURCE_BEHAVIORAL,
|
||||
|
||||
|
||||
SUBCIRCUIT,
|
||||
CODEMODEL,
|
||||
RAWSPICE
|
||||
)
|
||||
|
||||
struct INFO
|
||||
{
|
||||
DEVICE_TYPE deviceType;
|
||||
wxString fieldValue;
|
||||
wxString description;
|
||||
};
|
||||
|
||||
|
||||
struct PARAM
|
||||
{
|
||||
enum class DIR
|
||||
{
|
||||
IN,
|
||||
OUT,
|
||||
INOUT
|
||||
};
|
||||
|
||||
enum class CATEGORY
|
||||
{
|
||||
PRINCIPAL,
|
||||
DC,
|
||||
CAPACITANCE,
|
||||
TEMPERATURE,
|
||||
NOISE,
|
||||
DISTRIBUTED_QUANTITIES,
|
||||
GEOMETRY,
|
||||
LIMITING_VALUES,
|
||||
ADVANCED,
|
||||
FLAGS,
|
||||
INITIAL_CONDITIONS,
|
||||
SUPERFLUOUS
|
||||
};
|
||||
|
||||
struct FLAGS {}; // Legacy.
|
||||
|
||||
struct INFO
|
||||
{
|
||||
wxString name;
|
||||
unsigned int id = 0; // Legacy.
|
||||
DIR dir;
|
||||
SIM_VALUE_BASE::TYPE type;
|
||||
FLAGS flags = {}; // Legacy
|
||||
wxString unit;
|
||||
CATEGORY category;
|
||||
wxString defaultValue = "";
|
||||
wxString defaultValueOfOtherVariant = ""; // Legacy.
|
||||
wxString description;
|
||||
};
|
||||
|
||||
std::unique_ptr<SIM_VALUE_BASE> value;
|
||||
const INFO& info;
|
||||
bool isOtherVariant = false; // Legacy.
|
||||
|
||||
PARAM( const INFO& aInfo ) :
|
||||
value( SIM_VALUE_BASE::Create( aInfo.type ) ),
|
||||
info( aInfo )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
static DEVICE_INFO DeviceTypeInfo( DEVICE_TYPE aDeviceType );
|
||||
|
||||
static INFO TypeInfo( TYPE aType );
|
||||
|
||||
template <typename T>
|
||||
static TYPE ReadTypeFromFields( const std::vector<T>& aFields );
|
||||
|
||||
template <typename T>
|
||||
static std::unique_ptr<SIM_MODEL> Create( const std::vector<T>& aFields );
|
||||
|
||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType );
|
||||
|
||||
|
||||
// Move semantics.
|
||||
// Rule of five.
|
||||
virtual ~SIM_MODEL() = default;
|
||||
SIM_MODEL() = delete;
|
||||
SIM_MODEL( const SIM_MODEL& aOther ) = delete;
|
||||
SIM_MODEL( SIM_MODEL&& aOther ) = default;
|
||||
SIM_MODEL& operator=(SIM_MODEL&& aOther ) = default;
|
||||
|
||||
SIM_MODEL( TYPE aType );
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL( const std::vector<T>& aFields );
|
||||
|
||||
|
||||
template <typename T>
|
||||
void WriteFields( std::vector<T>& aFields );
|
||||
|
||||
// C++ doesn't allow virtual template methods, so we do this:
|
||||
virtual void DoWriteSchFields( std::vector<SCH_FIELD>& aFields );
|
||||
virtual void DoWriteLibFields( std::vector<LIB_FIELD>& aFields );
|
||||
|
||||
virtual void WriteCode( wxString& aCode ) = 0;
|
||||
|
||||
TYPE GetType() { return m_type; }
|
||||
|
||||
wxString GetFile() { return m_file; }
|
||||
void SetFile( const wxString& aFile ) { m_file = aFile; }
|
||||
|
||||
std::vector<PARAM>& Params() { return m_params; }
|
||||
|
||||
|
||||
private:
|
||||
TYPE m_type;
|
||||
wxString m_file;
|
||||
std::vector<PARAM> m_params;
|
||||
|
||||
|
||||
template <typename T>
|
||||
static wxString getFieldValue( const std::vector<T>& aFields, const wxString& aFieldName );
|
||||
|
||||
template <typename T>
|
||||
static void setFieldValue( std::vector<T>& aFields, const wxString& aFieldName,
|
||||
const wxString& aValue );
|
||||
|
||||
|
||||
virtual wxString generateParamValuePairs();
|
||||
virtual void parseParamValuePairs( const wxString& aParamValuePairs );
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_H
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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/sim_model_behavioral.h>
|
||||
|
||||
SIM_MODEL_BEHAVIORAL::SIM_MODEL_BEHAVIORAL( TYPE aType ) : SIM_MODEL( aType )
|
||||
{
|
||||
static PARAM::INFO resistor = makeParamInfo( "r", "Expression for resistance", "ohm" );
|
||||
static PARAM::INFO capacitor = makeParamInfo( "c", "Expression for capacitance", "F" );
|
||||
static PARAM::INFO inductor = makeParamInfo( "l", "Expression for inductance", "H" );
|
||||
static PARAM::INFO vsource = makeParamInfo( "v", "Expression for voltage", "V" );
|
||||
static PARAM::INFO isource = makeParamInfo( "i", "Expression for current", "A" );
|
||||
|
||||
switch( aType )
|
||||
{
|
||||
case TYPE::RESISTOR_BEHAVIORAL: Params().emplace_back( resistor ); break;
|
||||
case TYPE::CAPACITOR_BEHAVIORAL: Params().emplace_back( capacitor ); break;
|
||||
case TYPE::INDUCTOR_BEHAVIORAL: Params().emplace_back( inductor ); break;
|
||||
case TYPE::VSOURCE_BEHAVIORAL: Params().emplace_back( vsource ); break;
|
||||
case TYPE::ISOURCE_BEHAVIORAL: Params().emplace_back( isource ); break;
|
||||
default:
|
||||
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_IDEAL" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_BEHAVIORAL::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
SIM_MODEL::PARAM::INFO SIM_MODEL_BEHAVIORAL::makeParamInfo( wxString name, wxString description,
|
||||
wxString unit )
|
||||
{
|
||||
SIM_MODEL::PARAM::INFO paramInfo = {};
|
||||
|
||||
paramInfo.name = name;
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = unit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.description = description;
|
||||
|
||||
return paramInfo;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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_MODEL_BEHAVIORAL_H
|
||||
#define SIM_MODEL_BEHAVIORAL_H
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
|
||||
|
||||
class SIM_MODEL_BEHAVIORAL : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
SIM_MODEL_BEHAVIORAL( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
|
||||
private:
|
||||
static PARAM::INFO makeParamInfo( wxString name, wxString description, wxString unit );
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_BEHAVIORAL_H
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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/sim_model_codemodel.h>
|
||||
|
||||
SIM_MODEL_CODEMODEL::SIM_MODEL_CODEMODEL( TYPE aType ) : SIM_MODEL( aType )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_CODEMODEL::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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_MODEL_CODEMODEL_H
|
||||
#define SIM_MODEL_CODEMODEL_H
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
|
||||
|
||||
class SIM_MODEL_CODEMODEL : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
SIM_MODEL_CODEMODEL( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_CODEMODEL_H
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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/sim_model_ideal.h>
|
||||
|
||||
using PARAM = SIM_MODEL::PARAM;
|
||||
|
||||
|
||||
SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType ) : SIM_MODEL( aType )
|
||||
{
|
||||
static PARAM::INFO resistor = makeParamInfo( "r", "Resistance", "ohm" );
|
||||
static PARAM::INFO capacitor = makeParamInfo( "c", "Capacitance", "F" );
|
||||
static PARAM::INFO inductor = makeParamInfo( "l", "Inductance", "H" );
|
||||
|
||||
switch( aType )
|
||||
{
|
||||
case TYPE::RESISTOR_IDEAL: Params().emplace_back( resistor ); break;
|
||||
case TYPE::CAPACITOR_IDEAL: Params().emplace_back( capacitor ); break;
|
||||
case TYPE::INDUCTOR_IDEAL: Params().emplace_back( inductor ); break;
|
||||
default:
|
||||
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_IDEAL" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_IDEAL::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
PARAM::INFO SIM_MODEL_IDEAL::makeParamInfo( wxString aName, wxString aDescription, wxString aUnit )
|
||||
{
|
||||
SIM_MODEL::PARAM::INFO paramInfo = {};
|
||||
|
||||
paramInfo.name = aName;
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.description = aDescription;
|
||||
|
||||
return paramInfo;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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_MODEL_IDEAL_H
|
||||
#define SIM_MODEL_IDEAL_H
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
|
||||
|
||||
class SIM_MODEL_IDEAL : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
SIM_MODEL_IDEAL( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
|
||||
private:
|
||||
static PARAM::INFO makeParamInfo( wxString aName, wxString aDescription, wxString aUnit );
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_IDEAL_H
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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/sim_model_ngspice.h>
|
||||
|
||||
using TYPE = SIM_MODEL::TYPE;
|
||||
|
||||
|
||||
SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType ) : SIM_MODEL( aType )
|
||||
{
|
||||
const NGSPICE::MODEL_INFO& modelInfo = NGSPICE::ModelInfo( getModelType() );
|
||||
|
||||
for( const SIM_MODEL::PARAM::INFO& paramInfo : modelInfo.modelParams )
|
||||
{
|
||||
Params().emplace_back( paramInfo );
|
||||
Params().back().isOtherVariant = getIsOtherVariant();
|
||||
}
|
||||
|
||||
for( const SIM_MODEL::PARAM::INFO& paramInfo : modelInfo.instanceParams )
|
||||
{
|
||||
Params().emplace_back( paramInfo );
|
||||
Params().back().isOtherVariant = getIsOtherVariant();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_NGSPICE::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
NGSPICE::MODEL_TYPE SIM_MODEL_NGSPICE::getModelType()
|
||||
{
|
||||
switch( GetType() )
|
||||
{
|
||||
case TYPE::NONE: return NGSPICE::MODEL_TYPE::NONE;
|
||||
case TYPE::RESISTOR_ADVANCED: return NGSPICE::MODEL_TYPE::RESISTOR;
|
||||
case TYPE::CAPACITOR_ADVANCED: return NGSPICE::MODEL_TYPE::CAPACITOR;
|
||||
case TYPE::INDUCTOR_ADVANCED: return NGSPICE::MODEL_TYPE::INDUCTOR;
|
||||
case TYPE::TLINE_LOSSY: return NGSPICE::MODEL_TYPE::LTRA;
|
||||
case TYPE::TLINE_LOSSLESS: return NGSPICE::MODEL_TYPE::TRANLINE;
|
||||
case TYPE::TLINE_UNIFORM_RC: return NGSPICE::MODEL_TYPE::URC;
|
||||
case TYPE::TLINE_KSPICE: return NGSPICE::MODEL_TYPE::TRANSLINE;
|
||||
case TYPE::SWITCH_VCTRL: return NGSPICE::MODEL_TYPE::SWITCH;
|
||||
case TYPE::SWITCH_ICTRL: return NGSPICE::MODEL_TYPE::CSWITCH;
|
||||
case TYPE::DIODE: return NGSPICE::MODEL_TYPE::DIODE;
|
||||
|
||||
case TYPE::NPN_GUMMEL_POON:
|
||||
case TYPE::PNP_GUMMEL_POON: return NGSPICE::MODEL_TYPE::BJT;
|
||||
case TYPE::NPN_VBIC:
|
||||
case TYPE::PNP_VBIC: return NGSPICE::MODEL_TYPE::VBIC;
|
||||
case TYPE::NPN_HICUM_L2:
|
||||
case TYPE::PNP_HICUM_L2: return NGSPICE::MODEL_TYPE::HICUM2;
|
||||
|
||||
case TYPE::NJF_SHICHMAN_HODGES:
|
||||
case TYPE::PJF_SHICHMAN_HODGES: return NGSPICE::MODEL_TYPE::JFET;
|
||||
case TYPE::NJF_PARKER_SKELLERN:
|
||||
case TYPE::PJF_PARKER_SKELLERN: return NGSPICE::MODEL_TYPE::JFET2;
|
||||
|
||||
case TYPE::NMES_STATZ:
|
||||
case TYPE::PMES_STATZ: return NGSPICE::MODEL_TYPE::MES;
|
||||
case TYPE::NMES_YTTERDAL:
|
||||
case TYPE::PMES_YTTERDAL: return NGSPICE::MODEL_TYPE::MESA;
|
||||
case TYPE::NMES_HFET1:
|
||||
case TYPE::PMES_HFET1: return NGSPICE::MODEL_TYPE::HFET1;
|
||||
case TYPE::PMES_HFET2:
|
||||
case TYPE::NMES_HFET2: return NGSPICE::MODEL_TYPE::HFET2;
|
||||
|
||||
case TYPE::NMOS_MOS1:
|
||||
case TYPE::PMOS_MOS1: return NGSPICE::MODEL_TYPE::MOS1;
|
||||
case TYPE::NMOS_MOS2:
|
||||
case TYPE::PMOS_MOS2: return NGSPICE::MODEL_TYPE::MOS2;
|
||||
case TYPE::NMOS_MOS3:
|
||||
case TYPE::PMOS_MOS3: return NGSPICE::MODEL_TYPE::MOS3;
|
||||
case TYPE::NMOS_BSIM1:
|
||||
case TYPE::PMOS_BSIM1: return NGSPICE::MODEL_TYPE::BSIM1;
|
||||
case TYPE::NMOS_BSIM2:
|
||||
case TYPE::PMOS_BSIM2: return NGSPICE::MODEL_TYPE::BSIM2;
|
||||
case TYPE::NMOS_MOS6:
|
||||
case TYPE::PMOS_MOS6: return NGSPICE::MODEL_TYPE::MOS6;
|
||||
case TYPE::NMOS_BSIM3:
|
||||
case TYPE::PMOS_BSIM3: return NGSPICE::MODEL_TYPE::BSIM3;
|
||||
case TYPE::NMOS_MOS9:
|
||||
case TYPE::PMOS_MOS9: return NGSPICE::MODEL_TYPE::MOS9;
|
||||
case TYPE::NMOS_B4SOI:
|
||||
case TYPE::PMOS_B4SOI: return NGSPICE::MODEL_TYPE::B4SOI;
|
||||
case TYPE::NMOS_BSIM4:
|
||||
case TYPE::PMOS_BSIM4: return NGSPICE::MODEL_TYPE::BSIM4;
|
||||
case TYPE::NMOS_B3SOIFD:
|
||||
case TYPE::PMOS_B3SOIFD: return NGSPICE::MODEL_TYPE::B3SOIFD;
|
||||
case TYPE::NMOS_B3SOIDD:
|
||||
case TYPE::PMOS_B3SOIDD: return NGSPICE::MODEL_TYPE::B3SOIDD;
|
||||
case TYPE::NMOS_B3SOIPD:
|
||||
case TYPE::PMOS_B3SOIPD: return NGSPICE::MODEL_TYPE::B3SOIPD;
|
||||
case TYPE::NMOS_HISIM2:
|
||||
case TYPE::PMOS_HISIM2: return NGSPICE::MODEL_TYPE::HISIM2;
|
||||
case TYPE::NMOS_HISIM_HV1:
|
||||
case TYPE::PMOS_HISIM_HV1: return NGSPICE::MODEL_TYPE::HISIMHV1;
|
||||
case TYPE::NMOS_HISIM_HV2:
|
||||
case TYPE::PMOS_HISIM_HV2: return NGSPICE::MODEL_TYPE::HISIMHV2;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_NGSPICE" );
|
||||
return NGSPICE::MODEL_TYPE::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SIM_MODEL_NGSPICE::getIsOtherVariant()
|
||||
{
|
||||
switch( GetType() )
|
||||
{
|
||||
case TYPE::PNP_GUMMEL_POON:
|
||||
case TYPE::PNP_VBIC:
|
||||
case TYPE::PNP_HICUM_L2:
|
||||
case TYPE::PJF_SHICHMAN_HODGES:
|
||||
case TYPE::PJF_PARKER_SKELLERN:
|
||||
case TYPE::PMES_STATZ:
|
||||
case TYPE::PMES_YTTERDAL:
|
||||
case TYPE::PMES_HFET1:
|
||||
case TYPE::PMES_HFET2:
|
||||
case TYPE::PMOS_MOS1:
|
||||
case TYPE::PMOS_MOS2:
|
||||
case TYPE::PMOS_MOS3:
|
||||
case TYPE::PMOS_BSIM1:
|
||||
case TYPE::PMOS_BSIM2:
|
||||
case TYPE::PMOS_MOS6:
|
||||
case TYPE::PMOS_BSIM3:
|
||||
case TYPE::PMOS_MOS9:
|
||||
case TYPE::PMOS_B4SOI:
|
||||
case TYPE::PMOS_BSIM4:
|
||||
case TYPE::PMOS_B3SOIFD:
|
||||
case TYPE::PMOS_B3SOIDD:
|
||||
case TYPE::PMOS_B3SOIPD:
|
||||
case TYPE::PMOS_HISIM2:
|
||||
case TYPE::PMOS_HISIM_HV1:
|
||||
case TYPE::PMOS_HISIM_HV2:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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_MODEL_NGSPICE_H
|
||||
#define SIM_MODEL_NGSPICE_H
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
#include <sim/ngspice.h>
|
||||
|
||||
|
||||
class SIM_MODEL_NGSPICE : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
SIM_MODEL_NGSPICE( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
|
||||
private:
|
||||
NGSPICE::MODEL_TYPE getModelType();
|
||||
bool getIsOtherVariant();
|
||||
};
|
||||
|
||||
#endif /* SIM_MODEL_NGSPICE_H */
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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/sim_model_rawspice.h>
|
||||
|
||||
|
||||
SIM_MODEL_RAWSPICE::SIM_MODEL_RAWSPICE( TYPE aType ) : SIM_MODEL( aType )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_RAWSPICE::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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_MODEL_RAWSPICE_H
|
||||
#define SIM_MODEL_RAWSPICE_H
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
|
||||
|
||||
class SIM_MODEL_RAWSPICE : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
SIM_MODEL_RAWSPICE( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_RAWSPICE_H
|
|
@ -0,0 +1,690 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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/sim_model_source.h>
|
||||
|
||||
using PARAM = SIM_MODEL::PARAM;
|
||||
|
||||
|
||||
SIM_MODEL_SOURCE::SIM_MODEL_SOURCE( TYPE aType ) : SIM_MODEL( aType )
|
||||
{
|
||||
for( const PARAM::INFO& paramInfo : makeParams( aType ) )
|
||||
Params().emplace_back( paramInfo );
|
||||
}
|
||||
|
||||
|
||||
const std::vector<PARAM::INFO>& SIM_MODEL_SOURCE::makeParams( TYPE aType )
|
||||
{
|
||||
static std::vector<PARAM::INFO> vpulse = makePulse( "v", "V" );
|
||||
static std::vector<PARAM::INFO> ipulse = makePulse( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vsin = makeSin( "v", "V" );
|
||||
static std::vector<PARAM::INFO> isin = makeSin( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vexp = makeExp( "v", "V" );
|
||||
static std::vector<PARAM::INFO> iexp = makeExp( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vsfam = makeSfam( "v", "V" );
|
||||
static std::vector<PARAM::INFO> isfam = makeSfam( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vsffm = makeSffm( "v", "V" );
|
||||
static std::vector<PARAM::INFO> isffm = makeSffm( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vpwl = makePwl( "v", "Voltage", "V" );
|
||||
static std::vector<PARAM::INFO> ipwl = makePwl( "i", "Current", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vwhitenoise = makeWhiteNoise( "v", "V" );
|
||||
static std::vector<PARAM::INFO> iwhitenoise = makeWhiteNoise( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vpinknoise = makePinkNoise( "v", "V" );
|
||||
static std::vector<PARAM::INFO> ipinknoise = makePinkNoise( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vburstnoise = makeBurstNoise( "v", "V" );
|
||||
static std::vector<PARAM::INFO> iburstnoise = makeBurstNoise( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vrandomuniform = makeRandomUniform( "v", "V" );
|
||||
static std::vector<PARAM::INFO> irandomuniform = makeRandomUniform( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vrandomnormal = makeRandomNormal( "v", "V" );
|
||||
static std::vector<PARAM::INFO> irandomnormal = makeRandomNormal( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vrandomexp = makeRandomExp( "v", "V" );
|
||||
static std::vector<PARAM::INFO> irandomexp = makeRandomExp( "i", "A" );
|
||||
|
||||
static std::vector<PARAM::INFO> vrandompoisson = makeRandomPoisson( "v", "V" );
|
||||
static std::vector<PARAM::INFO> irandompoisson = makeRandomPoisson( "i", "A" );
|
||||
|
||||
switch( aType )
|
||||
{
|
||||
case TYPE::VSOURCE_PULSE: return vpulse;
|
||||
case TYPE::ISOURCE_PULSE: return ipulse;
|
||||
case TYPE::VSOURCE_SIN: return vsin;
|
||||
case TYPE::ISOURCE_SIN: return isin;
|
||||
case TYPE::VSOURCE_EXP: return vexp;
|
||||
case TYPE::ISOURCE_EXP: return iexp;
|
||||
case TYPE::VSOURCE_SFAM: return vsfam;
|
||||
case TYPE::ISOURCE_SFAM: return isfam;
|
||||
case TYPE::VSOURCE_SFFM: return vsffm;
|
||||
case TYPE::ISOURCE_SFFM: return isffm;
|
||||
case TYPE::VSOURCE_PWL: return vpwl;
|
||||
case TYPE::ISOURCE_PWL: return ipwl;
|
||||
case TYPE::VSOURCE_WHITE_NOISE: return vwhitenoise;
|
||||
case TYPE::ISOURCE_WHITE_NOISE: return iwhitenoise;
|
||||
case TYPE::VSOURCE_PINK_NOISE: return vpinknoise;
|
||||
case TYPE::ISOURCE_PINK_NOISE: return ipinknoise;
|
||||
case TYPE::VSOURCE_BURST_NOISE: return vburstnoise;
|
||||
case TYPE::ISOURCE_BURST_NOISE: return iburstnoise;
|
||||
case TYPE::VSOURCE_RANDOM_UNIFORM: return vrandomuniform;
|
||||
case TYPE::ISOURCE_RANDOM_UNIFORM: return irandomuniform;
|
||||
case TYPE::VSOURCE_RANDOM_NORMAL: return vrandomnormal;
|
||||
case TYPE::ISOURCE_RANDOM_NORMAL: return irandomnormal;
|
||||
case TYPE::VSOURCE_RANDOM_EXP: return vrandomexp;
|
||||
case TYPE::ISOURCE_RANDOM_EXP: return irandomexp;
|
||||
case TYPE::VSOURCE_RANDOM_POISSON: return vrandompoisson;
|
||||
case TYPE::ISOURCE_RANDOM_POISSON: return irandompoisson;
|
||||
default:
|
||||
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_SOURCE" );
|
||||
static std::vector<PARAM::INFO> empty;
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_SOURCE::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePulse( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = aPrefix + "1";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Initial value";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = aPrefix + "2";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Initial value";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "td";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Delay";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "tr";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "tstep";
|
||||
paramInfo.description = "Rise time";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "tf";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "tstep";
|
||||
paramInfo.description = "Fall time";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "pw";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "tstop";
|
||||
paramInfo.description = "Pulse width";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "per";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "tstop";
|
||||
paramInfo.description = "Period";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "phase";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "deg";
|
||||
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Phase";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSin( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = aPrefix + "o";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "DC offset";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = aPrefix + "a";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Amplitude";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "freq";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "Hz";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "1/tstop";
|
||||
paramInfo.description = "Frequency";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "td";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Delay";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "theta";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "1/s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Damping factor";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "phase";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "deg";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Phase";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeExp( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = aPrefix + "1";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Initial value";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = aPrefix + "2";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Pulsed value";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "td1";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Rise delay time";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "tau1";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "tstep";
|
||||
paramInfo.description = "Rise time constant";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "td2";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "td1+tstep";
|
||||
paramInfo.description = "Fall delay time";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "tau2";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "tstep";
|
||||
paramInfo.description = "Fall time constant";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSfam( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = aPrefix + "o";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "DC offset";
|
||||
|
||||
paramInfo.name = aPrefix + "a";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Amplitude";
|
||||
|
||||
paramInfos.push_back( paramInfo );
|
||||
paramInfo.name = "mo";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Modulating signal offset";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "fc";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "Hz";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Carrier frequency";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "mf";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "Hz";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Modulating frequency";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSffm( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = aPrefix + "o";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "DC offset";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = aPrefix + "a";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Amplitude";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "fc";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "Hz";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "1/tstop";
|
||||
paramInfo.description = "Carrier frequency";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "mdi";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Modulation index";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "fs";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "Hz";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "1/tstop";
|
||||
paramInfo.description = "Signal frequency";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "phasec";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "deg";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Carrier phase";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "phases";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "deg";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Signal phase";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePwl( wxString aPrefix, wxString aQuantity,
|
||||
wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = "t";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT_VECTOR;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Time vector";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = aPrefix;
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT_VECTOR;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = aQuantity + " vector";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "repeat";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::BOOL;
|
||||
paramInfo.unit = "";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "Repeat forever";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "td";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Delay";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeWhiteNoise( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = aPrefix + "o";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "";
|
||||
paramInfo.description = "DC offset";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "na";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "White noise RMS amplitude";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "rtsam";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Burst noise amplitude";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePinkNoise( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = "nalpha";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "1/f noise exponent";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "namp";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "1/f noise RMS amplitude";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "nt";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Time step";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeBurstNoise( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = "rtscapt";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Burst noise trap capture time";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "rtsemt";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Burst noise trap emission time";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "nt";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Time step";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomUniform( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = "min";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "-0.5";
|
||||
paramInfo.description = "Min. value";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "max";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0.5";
|
||||
paramInfo.description = "Max. value";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "td";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Delay";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomNormal( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = "mean";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Mean";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "stddev";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "1";
|
||||
paramInfo.description = "Standard deviation";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "td";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Delay";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomExp( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = "offset";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Offset";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "mean";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "1";
|
||||
paramInfo.description = "Mean";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "td";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Delay";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomPoisson( wxString aPrefix, wxString aUnit )
|
||||
{
|
||||
std::vector<PARAM::INFO> paramInfos;
|
||||
PARAM::INFO paramInfo;
|
||||
|
||||
paramInfo.name = "offset";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Offset";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "lambda";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = aUnit;
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "1";
|
||||
paramInfo.description = "Mean";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
paramInfo.name = "td";
|
||||
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
|
||||
paramInfo.unit = "s";
|
||||
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
|
||||
paramInfo.defaultValue = "0";
|
||||
paramInfo.description = "Delay";
|
||||
paramInfos.push_back( paramInfo );
|
||||
|
||||
return paramInfos;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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_MODEL_SOURCE_H
|
||||
#define SIM_MODEL_SOURCE_H
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
|
||||
|
||||
class SIM_MODEL_SOURCE : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
SIM_MODEL_SOURCE( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
|
||||
private:
|
||||
static const std::vector<PARAM::INFO>& makeParams( TYPE aType );
|
||||
|
||||
static std::vector<PARAM::INFO> makePulse( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeSin( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeExp( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeSfam( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeSffm( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makePwl( wxString aPrefix, wxString aQuantity, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeWhiteNoise( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makePinkNoise( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeBurstNoise( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeRandomUniform( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeRandomNormal( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeRandomExp( wxString aPrefix, wxString aUnit );
|
||||
static std::vector<PARAM::INFO> makeRandomPoisson( wxString aPrefix, wxString aUnit );
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_SOURCE_H
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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/sim_model_subcircuit.h>
|
||||
|
||||
SIM_MODEL_SUBCIRCUIT::SIM_MODEL_SUBCIRCUIT( TYPE aType ) : SIM_MODEL( aType )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_SUBCIRCUIT::WriteCode( wxString& aCode )
|
||||
{
|
||||
// TODO
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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_MODEL_SUBCIRCUIT_H
|
||||
#define SIM_MODEL_SUBCIRCUIT_H
|
||||
|
||||
#include <sim/sim_model.h>
|
||||
|
||||
|
||||
class SIM_MODEL_SUBCIRCUIT : public SIM_MODEL
|
||||
{
|
||||
public:
|
||||
SIM_MODEL_SUBCIRCUIT( TYPE aType );
|
||||
|
||||
void WriteCode( wxString& aCode ) override;
|
||||
};
|
||||
|
||||
#endif // SIM_MODEL_SUBCIRCUIT_H
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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/sim_value.h>
|
||||
#include <locale_io.h>
|
||||
#include <complex>
|
||||
|
||||
|
||||
std::unique_ptr<SIM_VALUE_BASE> SIM_VALUE_BASE::Create( TYPE aType, wxString aString )
|
||||
{
|
||||
std::unique_ptr<SIM_VALUE_BASE> value = SIM_VALUE_BASE::Create( aType );
|
||||
value->FromString( aString );
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<SIM_VALUE_BASE> SIM_VALUE_BASE::Create( TYPE aType )
|
||||
{
|
||||
switch( aType )
|
||||
{
|
||||
case TYPE::BOOL: return std::make_unique<SIM_VALUE<bool>>();
|
||||
case TYPE::INT: return std::make_unique<SIM_VALUE<long>>();
|
||||
case TYPE::FLOAT: return std::make_unique<SIM_VALUE<double>>();
|
||||
case TYPE::COMPLEX: return std::make_unique<SIM_VALUE<std::complex<double>>>();
|
||||
case TYPE::STRING: return std::make_unique<SIM_VALUE<wxString>>();
|
||||
case TYPE::BOOL_VECTOR: return std::make_unique<SIM_VALUE<bool>>();
|
||||
case TYPE::INT_VECTOR: return std::make_unique<SIM_VALUE<long>>();
|
||||
case TYPE::FLOAT_VECTOR: return std::make_unique<SIM_VALUE<double>>();
|
||||
case TYPE::COMPLEX_VECTOR: return std::make_unique<SIM_VALUE<std::complex<double>>>();
|
||||
}
|
||||
|
||||
wxFAIL_MSG( "Unknown SIM_VALUE type" );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void SIM_VALUE_BASE::operator=( const wxString& aString )
|
||||
{
|
||||
FromString( aString );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
SIM_VALUE<T>::SIM_VALUE( const T& aValue ) : m_value(aValue)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void SIM_VALUE<T>::FromString( const wxString& aString )
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
wxString SIM_VALUE<T>::ToString() const
|
||||
{
|
||||
static_assert( std::is_same<T, std::vector<T>>::value );
|
||||
|
||||
wxString string = "";
|
||||
|
||||
for( auto it = m_value.cbegin(); it != m_value.cend(); it++ )
|
||||
{
|
||||
string += SIM_VALUE<T>( *it ).ToString();
|
||||
string += ",";
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
wxString SIM_VALUE<bool>::ToString() const
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
return wxString::Format( "%d", m_value );
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
wxString SIM_VALUE<long>::ToString() const
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
return wxString::Format( "%d", m_value );
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
wxString SIM_VALUE<double>::ToString() const
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
return wxString::Format( "%f", m_value );
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
wxString SIM_VALUE<std::complex<double>>::ToString() const
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
return wxString::Format( "%f+%fi", m_value.real(), m_value.imag() );
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
wxString SIM_VALUE<wxString>::ToString() const
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool SIM_VALUE<T>::operator==( const SIM_VALUE_BASE& aOther ) const
|
||||
{
|
||||
const SIM_VALUE* otherNumber = dynamic_cast<const SIM_VALUE*>( &aOther );
|
||||
|
||||
if( otherNumber )
|
||||
return m_value == otherNumber->m_value;
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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_VALUE_H
|
||||
#define SIM_VALUE_H
|
||||
|
||||
#include <memory>
|
||||
#include <wx/string.h>
|
||||
|
||||
class SIM_VALUE_BASE
|
||||
{
|
||||
public:
|
||||
enum class TYPE
|
||||
{
|
||||
BOOL,
|
||||
INT,
|
||||
FLOAT,
|
||||
COMPLEX,
|
||||
STRING,
|
||||
|
||||
BOOL_VECTOR,
|
||||
INT_VECTOR,
|
||||
FLOAT_VECTOR,
|
||||
COMPLEX_VECTOR
|
||||
};
|
||||
|
||||
static std::unique_ptr<SIM_VALUE_BASE> Create( TYPE aType, wxString aString );
|
||||
static std::unique_ptr<SIM_VALUE_BASE> Create( TYPE aType );
|
||||
|
||||
void operator=( const wxString& aString );
|
||||
virtual bool operator==( const SIM_VALUE_BASE& aOther ) const = 0;
|
||||
|
||||
virtual void FromString( const wxString& aString ) = 0;
|
||||
virtual wxString ToString() const = 0;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class SIM_VALUE : public SIM_VALUE_BASE
|
||||
{
|
||||
public:
|
||||
SIM_VALUE() = default;
|
||||
SIM_VALUE( const T& aValue );
|
||||
|
||||
void FromString( const wxString& aString ) override;
|
||||
wxString ToString() const override;
|
||||
|
||||
void operator=( const T& aValue );
|
||||
bool operator==( const SIM_VALUE_BASE& aOther ) const override;
|
||||
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
|
||||
#endif /* SIM_VALUE_H */
|
|
@ -1,309 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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 <iterator>
|
||||
#include <sim/spice_model.h>
|
||||
#include <pegtl.hpp>
|
||||
#include <pegtl/contrib/parse_tree.hpp>
|
||||
#include <locale_io.h>
|
||||
#include <lib_symbol.h>
|
||||
|
||||
/*namespace SPICE_MODEL_PARSER
|
||||
{
|
||||
using namespace tao::pegtl;
|
||||
|
||||
struct directive : sor<TAO_PEGTL_ISTRING( ".model" ),
|
||||
TAO_PEGTL_ISTRING( ".param" ),
|
||||
TAO_PEGTL_ISTRING( ".subckt" )> {};*//*
|
||||
|
||||
struct spaces : star<space> {};
|
||||
struct identifierNotFirstChar : sor<alnum, one<'!', '#', '$', '%', '[', ']', '_'>> {};
|
||||
struct identifier : seq<alpha, star<identifierNotFirstChar>> {};
|
||||
struct digits : plus<digit> {};
|
||||
|
||||
struct sign : opt<one<'+', '-'>> {};
|
||||
struct significand : sor<seq<digits, one<'.'>, opt<digits>>, seq<one<'.'>, digits>> {};
|
||||
struct exponent : opt<one<'e', 'E'>, sign, digits> {};
|
||||
struct metricSuffix : sor<TAO_PEGTL_ISTRING( "T" ),
|
||||
TAO_PEGTL_ISTRING( "G" ),
|
||||
TAO_PEGTL_ISTRING( "Meg" ),
|
||||
TAO_PEGTL_ISTRING( "K" ),
|
||||
TAO_PEGTL_ISTRING( "mil" ),
|
||||
TAO_PEGTL_ISTRING( "m" ),
|
||||
TAO_PEGTL_ISTRING( "u" ),
|
||||
TAO_PEGTL_ISTRING( "n" ),
|
||||
TAO_PEGTL_ISTRING( "p" ),
|
||||
TAO_PEGTL_ISTRING( "f" )> {};
|
||||
struct number : seq<sign, significand, exponent, metricSuffix> {};
|
||||
|
||||
struct modelModelType : sor<TAO_PEGTL_ISTRING( "R" ),
|
||||
TAO_PEGTL_ISTRING( "C" ),
|
||||
TAO_PEGTL_ISTRING( "L" ),
|
||||
TAO_PEGTL_ISTRING( "SW" ),
|
||||
TAO_PEGTL_ISTRING( "CSW" ),
|
||||
TAO_PEGTL_ISTRING( "URC" ),
|
||||
TAO_PEGTL_ISTRING( "LTRA" ),
|
||||
TAO_PEGTL_ISTRING( "D" ),
|
||||
TAO_PEGTL_ISTRING( "NPN" ),
|
||||
TAO_PEGTL_ISTRING( "PNP" ),
|
||||
TAO_PEGTL_ISTRING( "NJF" ),
|
||||
TAO_PEGTL_ISTRING( "PJF" ),
|
||||
TAO_PEGTL_ISTRING( "NMOS" ),
|
||||
TAO_PEGTL_ISTRING( "PMOS" ),
|
||||
TAO_PEGTL_ISTRING( "NMF" ),
|
||||
TAO_PEGTL_ISTRING( "PMF" ),
|
||||
TAO_PEGTL_ISTRING( "VDMOS" )> {};
|
||||
struct paramValuePair : seq<alnum, spaces, one<'='>, spaces, number> {};
|
||||
struct paramValuePairs : opt<paramValuePair, star<spaces, paramValuePair>> {};
|
||||
struct modelModelSpec : seq<modelModelType,
|
||||
spaces,
|
||||
one<'('>,
|
||||
spaces,
|
||||
|
||||
paramValuePairs,
|
||||
|
||||
spaces,
|
||||
one<')'>,
|
||||
spaces> {};
|
||||
struct modelModel : seq<TAO_PEGTL_ISTRING( ".model" ), identifier, modelModelSpec> {};
|
||||
|
||||
struct model : modelModel {};
|
||||
//struct model : sor<modelModel, paramModel, subcircuitModel> {};
|
||||
}*/
|
||||
|
||||
namespace SPICE_MODEL_PARSER
|
||||
{
|
||||
using namespace tao::pegtl;
|
||||
|
||||
struct spaces : star<space> {};
|
||||
struct digits : plus<digit> {};
|
||||
|
||||
struct sign : opt<one<'+', '-'>> {};
|
||||
struct significand : sor<seq<digits, opt<one<'.'>, opt<digits>>>, seq<one<'.'>, digits>> {};
|
||||
struct exponent : opt<one<'e', 'E'>, sign, digits> {};
|
||||
struct metricSuffix : opt<sor<TAO_PEGTL_ISTRING( "T" ),
|
||||
TAO_PEGTL_ISTRING( "G" ),
|
||||
TAO_PEGTL_ISTRING( "Meg" ),
|
||||
TAO_PEGTL_ISTRING( "K" ),
|
||||
TAO_PEGTL_ISTRING( "mil" ),
|
||||
TAO_PEGTL_ISTRING( "m" ),
|
||||
TAO_PEGTL_ISTRING( "u" ),
|
||||
TAO_PEGTL_ISTRING( "n" ),
|
||||
TAO_PEGTL_ISTRING( "p" ),
|
||||
TAO_PEGTL_ISTRING( "f" )>> {};
|
||||
|
||||
// TODO: Move the `number` grammar to the SPICE_VALUE class.
|
||||
struct number : seq<sign, significand, exponent, metricSuffix> {};
|
||||
|
||||
struct param : seq<alnum> {};
|
||||
|
||||
struct paramValuePair : seq<param, spaces, one<'='>, spaces, number> {};
|
||||
struct paramValuePairs : opt<paramValuePair, star<spaces, paramValuePair>> {};
|
||||
|
||||
template <typename Rule> struct paramValuePairsSelector : std::false_type {};
|
||||
template <> struct paramValuePairsSelector<param> : std::true_type {};
|
||||
template <> struct paramValuePairsSelector<number> : std::true_type {};
|
||||
}
|
||||
|
||||
|
||||
template SPICE_MODEL::TYPE SPICE_MODEL::ReadTypeFromFields( const std::vector<SCH_FIELD>* aFields );
|
||||
template SPICE_MODEL::TYPE SPICE_MODEL::ReadTypeFromFields( const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
SPICE_MODEL::TYPE SPICE_MODEL::ReadTypeFromFields( const std::vector<T>* aFields )
|
||||
{
|
||||
wxString typeFieldValue = getFieldValue( aFields, TYPE_FIELD );
|
||||
wxString deviceTypeFieldValue = getFieldValue( aFields, DEVICE_TYPE_FIELD );
|
||||
bool typeFound = false;
|
||||
|
||||
for( TYPE type : TYPE_ITERATOR() )
|
||||
{
|
||||
if( typeFieldValue == TypeInfo( type ).fieldValue )
|
||||
{
|
||||
typeFound = true;
|
||||
|
||||
if( deviceTypeFieldValue == DeviceTypeInfo( TypeInfo( type ).deviceType ).fieldValue )
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
if( !typeFound )
|
||||
throw KI_PARAM_ERROR( wxString::Format( _( "Invalid \"%s\" field value: \"%s\"" ),
|
||||
TYPE_FIELD, typeFieldValue ) );
|
||||
|
||||
throw KI_PARAM_ERROR( wxString::Format( _( "Invalid \"%s\" field value: \"%s\"" ),
|
||||
DEVICE_TYPE_FIELD, deviceTypeFieldValue ) );
|
||||
}
|
||||
|
||||
|
||||
SPICE_MODEL::SPICE_MODEL( TYPE aType ) : m_type( aType )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template SPICE_MODEL::SPICE_MODEL( const std::vector<SCH_FIELD>* aFields );
|
||||
template SPICE_MODEL::SPICE_MODEL( const std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
SPICE_MODEL::SPICE_MODEL( const std::vector<T>* aFields )
|
||||
: m_type( ReadTypeFromFields( aFields ) )
|
||||
{
|
||||
SetFile( getFieldValue( aFields, "Model_File" ) );
|
||||
parseParamValuePairs( getFieldValue( aFields, "Model_Params" ) );
|
||||
}
|
||||
|
||||
|
||||
SPICE_MODEL::SPICE_MODEL( const wxString& aCode )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template void SPICE_MODEL::WriteFields( std::vector<SCH_FIELD>* aFields );
|
||||
template void SPICE_MODEL::WriteFields( std::vector<LIB_FIELD>* aFields );
|
||||
|
||||
template <typename T>
|
||||
void SPICE_MODEL::WriteFields( std::vector<T>* aFields )
|
||||
{
|
||||
setFieldValue( aFields, DEVICE_TYPE_FIELD,
|
||||
DeviceTypeInfo( TypeInfo( m_type ).deviceType ).fieldValue );
|
||||
setFieldValue( aFields, TYPE_FIELD, TypeInfo( m_type ).fieldValue );
|
||||
setFieldValue( aFields, FILE_FIELD, GetFile() );
|
||||
setFieldValue( aFields, PARAMS_FIELD, generateParamValuePairs() );
|
||||
}
|
||||
|
||||
|
||||
void SPICE_MODEL::WriteCode( wxString& aCode )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SPICE_MODEL::parseParamValuePairs( const wxString& aParamValuePairs )
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
|
||||
tao::pegtl::string_input<> in( aParamValuePairs.ToStdString(), "from_input" );
|
||||
auto root = tao::pegtl::parse_tree::parse<SPICE_MODEL_PARSER::paramValuePairs,
|
||||
SPICE_MODEL_PARSER::paramValuePairsSelector>( in );
|
||||
|
||||
wxString paramName = "";
|
||||
|
||||
for( const auto& node : root->children )
|
||||
{
|
||||
if( node->is_type<SPICE_MODEL_PARSER::param>() )
|
||||
paramName = node->string();
|
||||
else if( node->is_type<SPICE_MODEL_PARSER::number>() )
|
||||
{
|
||||
wxASSERT( paramName != "" );
|
||||
|
||||
try
|
||||
{
|
||||
SPICE_VALUE value( node->string() );
|
||||
|
||||
/*if( !SetParamValue( paramName, value ) )
|
||||
{
|
||||
m_params.clear();
|
||||
throw KI_PARAM_ERROR( wxString::Format( _( "Unknown parameter \"%s\"" ),
|
||||
paramName ) );
|
||||
}*/
|
||||
}
|
||||
catch( KI_PARAM_ERROR& e )
|
||||
{
|
||||
m_params.clear();
|
||||
throw KI_PARAM_ERROR( wxString::Format( _( "Invalid \"%s\" parameter value: \"%s\"" ),
|
||||
paramName, e.What() ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
wxFAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxString SPICE_MODEL::generateParamValuePairs()
|
||||
{
|
||||
wxString result = "";
|
||||
|
||||
/*for( auto it = GetParams().cbegin(); it != GetParams().cend(); it++ )
|
||||
{
|
||||
result += it->first;
|
||||
result += "=";
|
||||
result += it->second.value.ToString();
|
||||
|
||||
if( std::next( it ) != GetParams().cend() )
|
||||
result += " ";
|
||||
}*/
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
wxString SPICE_MODEL::getFieldValue( const std::vector<T>* aFields, const wxString& aFieldName )
|
||||
{
|
||||
static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value );
|
||||
|
||||
auto fieldIt = std::find_if( aFields->begin(), aFields->end(),
|
||||
[&]( const T& f )
|
||||
{
|
||||
return f.GetName() == aFieldName;
|
||||
} );
|
||||
|
||||
if( fieldIt != aFields->end() )
|
||||
return fieldIt->GetText();
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void SPICE_MODEL::setFieldValue( std::vector<T>* aFields, const wxString& aFieldName,
|
||||
const wxString& aValue )
|
||||
{
|
||||
static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value );
|
||||
|
||||
auto fieldIt = std::find_if( aFields->begin(), aFields->end(),
|
||||
[&]( const T& f )
|
||||
{
|
||||
return f.GetName() == aFieldName;
|
||||
} );
|
||||
|
||||
if( fieldIt != aFields->end() )
|
||||
{
|
||||
fieldIt->SetText( aValue );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if constexpr( std::is_same<T, SCH_FIELD>::value )
|
||||
{
|
||||
wxASSERT( aFields->size() >= 1 );
|
||||
|
||||
SCH_ITEM* parent = static_cast<SCH_ITEM*>( aFields->at( 0 ).GetParent() );
|
||||
aFields->emplace_back( wxPoint(), aFields->size(), parent, aFieldName );
|
||||
}
|
||||
else if constexpr( std::is_same<T, LIB_FIELD>::value )
|
||||
aFields->emplace_back( aFields->size(), aFieldName );
|
||||
|
||||
aFields->back().SetText( aValue );
|
||||
}
|
|
@ -1,287 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mikolaj Wielgus
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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 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 SPICE_MODEL_H
|
||||
#define SPICE_MODEL_H
|
||||
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <enum_vector.h>
|
||||
#include <sch_field.h>
|
||||
#include <lib_field.h>
|
||||
#include <sim/ngspice.h>
|
||||
#include <sim/spice_value.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
class SPICE_MODEL
|
||||
{
|
||||
public:
|
||||
static constexpr auto DEVICE_TYPE_FIELD = "Model_Device";
|
||||
static constexpr auto TYPE_FIELD = "Model_Type";
|
||||
static constexpr auto FILE_FIELD = "Model_File";
|
||||
static constexpr auto PARAMS_FIELD = "Model_Params";
|
||||
|
||||
/*struct PARAM
|
||||
{
|
||||
SPICE_VALUE value;
|
||||
wxString description;
|
||||
wxString unit;
|
||||
};*/
|
||||
|
||||
|
||||
DEFINE_ENUM_CLASS_WITH_ITERATOR( DEVICE_TYPE,
|
||||
NONE,
|
||||
|
||||
RESISTOR,
|
||||
CAPACITOR,
|
||||
INDUCTOR,
|
||||
TLINE,
|
||||
|
||||
DIODE,
|
||||
BJT,
|
||||
JFET,
|
||||
MESFET,
|
||||
MOSFET,
|
||||
|
||||
VSOURCE,
|
||||
ISOURCE,
|
||||
|
||||
SUBCIRCUIT,
|
||||
CODEMODEL,
|
||||
RAWSPICE
|
||||
)
|
||||
|
||||
struct DEVICE_TYPE_INFO
|
||||
{
|
||||
wxString fieldValue;
|
||||
wxString description;
|
||||
};
|
||||
|
||||
static DEVICE_TYPE_INFO DeviceTypeInfo( DEVICE_TYPE aDeviceType )
|
||||
{
|
||||
switch( aDeviceType )
|
||||
{
|
||||
case DEVICE_TYPE::NONE: return {"", ""};
|
||||
case DEVICE_TYPE::RESISTOR: return {"RESISTOR", "Resistor"};
|
||||
case DEVICE_TYPE::CAPACITOR: return {"CAPACITOR", "Capacitor"};
|
||||
case DEVICE_TYPE::INDUCTOR: return {"INDUCTOR", "Inductor"};
|
||||
case DEVICE_TYPE::TLINE: return {"TLINE", "Transmission Line"};
|
||||
case DEVICE_TYPE::DIODE: return {"DIODE", "Diode"};
|
||||
case DEVICE_TYPE::BJT: return {"BJT", "BJT"};
|
||||
case DEVICE_TYPE::JFET: return {"JFET", "JFET"};
|
||||
case DEVICE_TYPE::MOSFET: return {"MOSFET", "MOSFET"};
|
||||
case DEVICE_TYPE::MESFET: return {"MESFET", "MESFET"};
|
||||
case DEVICE_TYPE::VSOURCE: return {"VSOURCE", "Voltage Source"};
|
||||
case DEVICE_TYPE::ISOURCE: return {"ISOURCE", "Current Source"};
|
||||
case DEVICE_TYPE::SUBCIRCUIT: return {"SUBCIRCUIT", "Subcircuit"};
|
||||
case DEVICE_TYPE::CODEMODEL: return {"CODEMODEL", "Code Model"};
|
||||
case DEVICE_TYPE::RAWSPICE: return {"RAWSPICE", "Raw Spice Element"};
|
||||
case DEVICE_TYPE::_ENUM_END: break;
|
||||
}
|
||||
|
||||
wxFAIL;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ENUM_CLASS_WITH_ITERATOR( TYPE,
|
||||
NONE,
|
||||
|
||||
RESISTOR_IDEAL,
|
||||
RESISTOR_SEMICONDUCTOR,
|
||||
|
||||
CAPACITOR_IDEAL,
|
||||
CAPACITOR_SEMICONDUCTOR,
|
||||
|
||||
INDUCTOR_IDEAL,
|
||||
INDUCTOR_IDEAL_COIL,
|
||||
|
||||
TLINE_LOSSY,
|
||||
TLINE_LOSSLESS,
|
||||
TLINE_DISTRIBUTED_RC,
|
||||
TLINE_KSPICE_LOSSY,
|
||||
|
||||
DIODE,
|
||||
|
||||
BJT_GUMMEL_POON,
|
||||
BJT_VBIC,
|
||||
//BJT_MEXTRAM,
|
||||
BJT_HICUM_L2,
|
||||
//BJT_HICUM_L0,
|
||||
|
||||
JFET_SHICHMAN_HODGES,
|
||||
JFET_PARKER_SKELLERN,
|
||||
|
||||
MESFET_STATZ,
|
||||
MESFET_YTTERDAL,
|
||||
MESFET_HFET1,
|
||||
MESFET_HFET2,
|
||||
|
||||
MOSFET_MOS1,
|
||||
MOSFET_MOS2,
|
||||
MOSFET_MOS3,
|
||||
MOSFET_BSIM1,
|
||||
MOSFET_BSIM2,
|
||||
MOSFET_MOS6,
|
||||
MOSFET_MOS9,
|
||||
MOSFET_BSIM3,
|
||||
MOSFET_B4SOI,
|
||||
MOSFET_BSIM4,
|
||||
//MOSFET_EKV2_6,
|
||||
//MOSFET_PSP,
|
||||
MOSFET_B3SOIFD,
|
||||
MOSFET_B3SOIDD,
|
||||
MOSFET_B3SOIPD,
|
||||
//MOSFET_STAG,
|
||||
MOSFET_HISIM2,
|
||||
MOSFET_HISIM_HV,
|
||||
|
||||
VSOURCE,
|
||||
ISOURCE,
|
||||
|
||||
SUBCIRCUIT,
|
||||
CODEMODEL,
|
||||
RAWSPICE
|
||||
)
|
||||
|
||||
struct TYPE_INFO
|
||||
{
|
||||
DEVICE_TYPE deviceType;
|
||||
//NGSPICE::MODEL_TYPE ngspiceModelType;
|
||||
wxString ngspicePrimitive;
|
||||
unsigned int ngspiceLevel;
|
||||
wxString fieldValue;
|
||||
wxString description;
|
||||
};
|
||||
|
||||
static TYPE_INFO TypeInfo( TYPE aType )
|
||||
{
|
||||
switch( aType )
|
||||
{
|
||||
case TYPE::NONE: return { DEVICE_TYPE::NONE, "", 0, "", "" };
|
||||
|
||||
case TYPE::RESISTOR_IDEAL: return { DEVICE_TYPE::RESISTOR, "R", 0, "IDEAL", "Ideal model" };
|
||||
case TYPE::RESISTOR_SEMICONDUCTOR: return { DEVICE_TYPE::RESISTOR, "R", 0, "SEMICONDUCTOR", "Semiconductor model" };
|
||||
|
||||
case TYPE::CAPACITOR_IDEAL: return { DEVICE_TYPE::CAPACITOR, "C", 0, "IDEAL", "Ideal model" };
|
||||
case TYPE::CAPACITOR_SEMICONDUCTOR: return { DEVICE_TYPE::CAPACITOR, "C", 0, "SEMICONDUCTOR", "Semiconductor model" };
|
||||
|
||||
case TYPE::INDUCTOR_IDEAL: return { DEVICE_TYPE::INDUCTOR, "L", 0, "IDEAL", "Ideal model" };
|
||||
case TYPE::INDUCTOR_IDEAL_COIL: return { DEVICE_TYPE::INDUCTOR, "L", 0, "LOSSLESS_COIL", "Lossless coil model" };
|
||||
|
||||
case TYPE::TLINE_LOSSY: return { DEVICE_TYPE::TLINE, "O", 0, "LOSSY", "Lossy model" };
|
||||
case TYPE::TLINE_LOSSLESS: return { DEVICE_TYPE::TLINE, "T", 0, "LOSSLESS", "Lossless model" };
|
||||
case TYPE::TLINE_DISTRIBUTED_RC: return { DEVICE_TYPE::TLINE, "U", 0, "DISTRIBUTED_RC", "Uniformly distributed RC model" };
|
||||
case TYPE::TLINE_KSPICE_LOSSY: return { DEVICE_TYPE::TLINE, "Y", 0, "KSPICE_LOSSY", "KSPICE lossy model" };
|
||||
|
||||
case TYPE::DIODE: return { DEVICE_TYPE::DIODE, "D", 0, "", "" };
|
||||
|
||||
case TYPE::BJT_GUMMEL_POON: return { DEVICE_TYPE::BJT, "Q", 1, "GUMMEL_POON", "Gummel-Poon model" };
|
||||
case TYPE::BJT_VBIC: return { DEVICE_TYPE::BJT, "Q", 4, "VBIC", "VBIC model" };
|
||||
//case TYPE::BJT_MEXTRAM: return { DEVICE_TYPE::BJT, "Q", 6, "MEXTRAM", "MEXTRAM model" };
|
||||
case TYPE::BJT_HICUM_L2: return { DEVICE_TYPE::BJT, "Q", 8, "HICUM_L2", "HICUM Level 2 model" };
|
||||
//case TYPE::BJT_HICUM_L0: return { DEVICE_TYPE::BJT, "Q", 7, "HICUM_L0", "HICUM Level 0 model" };
|
||||
|
||||
case TYPE::JFET_SHICHMAN_HODGES: return { DEVICE_TYPE::JFET, "J", 1, "SHICHMAN_HODGES", "Shichman-Hodges model" };
|
||||
case TYPE::JFET_PARKER_SKELLERN: return { DEVICE_TYPE::JFET, "J", 2, "PARKER_SKELLERN", "Parker-Skellern model" };
|
||||
|
||||
case TYPE::MESFET_STATZ: return { DEVICE_TYPE::MESFET, "Z", 1, "STATZ", "Statz model" };
|
||||
case TYPE::MESFET_YTTERDAL: return { DEVICE_TYPE::MESFET, "Z", 2, "YTTERDAL", "Ytterdal model" };
|
||||
case TYPE::MESFET_HFET1: return { DEVICE_TYPE::MESFET, "Z", 5, "HFET1", "HFET1 model" };
|
||||
case TYPE::MESFET_HFET2: return { DEVICE_TYPE::MESFET, "Z", 6, "HFET2", "HFET2 model" };
|
||||
|
||||
case TYPE::MOSFET_MOS1: return { DEVICE_TYPE::MOSFET, "M", 1, "MOS1", "Classical quadratic model (MOS1)" };
|
||||
case TYPE::MOSFET_MOS2: return { DEVICE_TYPE::MOSFET, "M", 2, "MOS2", "Grove-Frohman model (MOS2)" };
|
||||
case TYPE::MOSFET_MOS3: return { DEVICE_TYPE::MOSFET, "M", 3, "MOS3", "MOS3 model" };
|
||||
case TYPE::MOSFET_BSIM1: return { DEVICE_TYPE::MOSFET, "M", 4, "BSIM1", "BSIM1 model" };
|
||||
case TYPE::MOSFET_BSIM2: return { DEVICE_TYPE::MOSFET, "M", 5, "BSIM2", "BSIM2 model" };
|
||||
case TYPE::MOSFET_MOS6: return { DEVICE_TYPE::MOSFET, "M", 6, "MOS6", "MOS6 model" };
|
||||
case TYPE::MOSFET_BSIM3: return { DEVICE_TYPE::MOSFET, "M", 8, "BSIM3", "BSIM3 model" };
|
||||
case TYPE::MOSFET_MOS9: return { DEVICE_TYPE::MOSFET, "M", 9, "MOS9", "MOS9 model" };
|
||||
case TYPE::MOSFET_B4SOI: return { DEVICE_TYPE::MOSFET, "M", 10, "B4SOI", "BSIM4 SOI model (B4SOI)" };
|
||||
case TYPE::MOSFET_BSIM4: return { DEVICE_TYPE::MOSFET, "M", 14, "BSIM4", "BSIM4 model" };
|
||||
//case TYPE::MOSFET_EKV2_6: return { DEVICE_TYPE::MOSFET, "M", 44, "EKV2.6", "EKV2.6 model" };
|
||||
//case TYPE::MOSFET_PSP: return { DEVICE_TYPE::MOSFET, "M", 45, "PSP", "PSP model" };
|
||||
case TYPE::MOSFET_B3SOIFD: return { DEVICE_TYPE::MOSFET, "M", 55, "B3SOIFD", "B3SOIFD (BSIM3 fully depleted SOI) model" };
|
||||
case TYPE::MOSFET_B3SOIDD: return { DEVICE_TYPE::MOSFET, "M", 56, "B3SOIDD", "B3SOIDD (BSIM3 SOI, both fully and partially depleted) model" };
|
||||
case TYPE::MOSFET_B3SOIPD: return { DEVICE_TYPE::MOSFET, "M", 57, "B3SOIPD", "B3SOIPD (BSIM3 partially depleted SOI) model" };
|
||||
//case TYPE::MOSFET_STAG: return { DEVICE_TYPE::MOSFET, "M", 60, "STAG", "STAG model" };
|
||||
case TYPE::MOSFET_HISIM2: return { DEVICE_TYPE::MOSFET, "M", 68, "HiSIM2", "HiSIM2 model" };
|
||||
case TYPE::MOSFET_HISIM_HV: return { DEVICE_TYPE::MOSFET, "M", 73, "HiSIM_HV", "HiSIM_HV model" };
|
||||
|
||||
case TYPE::VSOURCE: return { DEVICE_TYPE::VSOURCE, "V", 0, "", "" };
|
||||
case TYPE::ISOURCE: return { DEVICE_TYPE::ISOURCE, "V", 0, "", "" };
|
||||
|
||||
case TYPE::SUBCIRCUIT: return { DEVICE_TYPE::SUBCIRCUIT, "X", 0, "", "" };
|
||||
case TYPE::CODEMODEL: return { DEVICE_TYPE::CODEMODEL, "A", 0, "", "" };
|
||||
case TYPE::RAWSPICE: return { DEVICE_TYPE::RAWSPICE, "", 0, "", "" };
|
||||
|
||||
case TYPE::_ENUM_END: break;
|
||||
}
|
||||
|
||||
wxFAIL;
|
||||
return { };
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static TYPE ReadTypeFromFields( const std::vector<T>* aFields );
|
||||
|
||||
|
||||
SPICE_MODEL( TYPE aType );
|
||||
|
||||
template <typename T>
|
||||
SPICE_MODEL( const std::vector<T>* aFields );
|
||||
|
||||
SPICE_MODEL( const wxString& aCode );
|
||||
|
||||
|
||||
template <typename T>
|
||||
void WriteFields( std::vector<T>* aFields );
|
||||
|
||||
void WriteCode( wxString& aCode );
|
||||
|
||||
|
||||
wxString GetFile() { return m_file; }
|
||||
void SetFile( const wxString& aFile ) { m_file = aFile; }
|
||||
|
||||
|
||||
private:
|
||||
TYPE m_type;
|
||||
wxString m_file;
|
||||
std::map<wxString, double> m_params;
|
||||
|
||||
|
||||
template <typename T>
|
||||
static wxString getFieldValue( const std::vector<T>* aFields, const wxString& aFieldName );
|
||||
|
||||
template <typename T>
|
||||
static void setFieldValue( std::vector<T>* aFields, const wxString& aFieldName,
|
||||
const wxString& aValue );
|
||||
|
||||
|
||||
wxString generateParamValuePairs();
|
||||
void parseParamValuePairs( const wxString& aParamValuePairs );
|
||||
};
|
||||
|
||||
#endif /* SPICE_MODEL_H */
|
|
@ -74,6 +74,7 @@ if( KICAD_SPICE )
|
|||
set( QA_EESCHEMA_SRCS
|
||||
${QA_EESCHEMA_SRCS}
|
||||
# Simulation tests
|
||||
sim/test_ngspice.cpp
|
||||
sim/test_ngspice_helpers.cpp
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.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
|
||||
*/
|
||||
|
||||
#include <qa_utils/wx_utils/unit_test_utils.h>
|
||||
#include <sim/ngspice.h>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE( Ngspice )
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( Models )
|
||||
{
|
||||
// Count the total number of model and instance parameters for each model so that there will be
|
||||
// an error if someone accidentally removes a parameter.
|
||||
|
||||
for( NGSPICE::MODEL_TYPE type : NGSPICE::MODEL_TYPE_ITERATOR() )
|
||||
{
|
||||
unsigned int modelParamCount = NGSPICE::ModelInfo( type ).modelParams.size();
|
||||
unsigned int instanceParamCount = NGSPICE::ModelInfo( type ).instanceParams.size();
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case NGSPICE::MODEL_TYPE::NONE:
|
||||
case NGSPICE::MODEL_TYPE::_ENUM_END:
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::RESISTOR:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 22 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 25 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::CAPACITOR:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 19 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 22 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::INDUCTOR:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 9 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 20 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::LTRA:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 18 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 9 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::TRANLINE:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 0 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 17 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::URC:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 7 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 5 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::TRANSLINE:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 6 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 3 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::DIODE:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 76 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 30 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::BJT:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 152 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 52 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::VBIC:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 117 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 44 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::HICUM2:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 149 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 60 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::JFET:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 28 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 28 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::JFET2:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 39 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 30 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::MES:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 22 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 25 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::MESA:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 51 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 30 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::HFET1:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 22 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 28 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::HFET2:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 19 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 28 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::MOS1:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 35 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 76 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::MOS2:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 42 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 76 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::MOS3:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 48 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 81 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::BSIM1:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 81 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 14 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::BSIM2:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 137 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 14 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::MOS6:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 42 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 78 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::BSIM3:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 429 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 46 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::MOS9:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 48 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 81 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::B4SOI:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 915 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 74 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::BSIM4:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 892 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 84 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::B3SOIFD:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 393 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 27 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::B3SOIDD:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 393 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 27 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::B3SOIPD:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 470 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 36 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::HISIM2:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 486 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 59 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::HISIMHV1:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 536 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 66 );
|
||||
break;
|
||||
|
||||
case NGSPICE::MODEL_TYPE::HISIMHV2:
|
||||
BOOST_CHECK_EQUAL( modelParamCount, 630 );
|
||||
BOOST_CHECK_EQUAL( instanceParamCount, 68 );
|
||||
break;
|
||||
|
||||
default:
|
||||
BOOST_FAIL( wxString::Format(
|
||||
"Unhandled type: %d "
|
||||
"(if you created a new type you need to handle it in this switch statement)",
|
||||
type ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue