Sim: Spice netlist exporter rewrite

Rewrite the spice exporter to work with the new simulation model
architecture and data model, with many bugfixes related to the latter
two along the way.
This commit is contained in:
Mikolaj Wielgus 2022-04-12 16:37:06 +02:00
parent ce84a48037
commit 6450ec6b85
82 changed files with 14019 additions and 9509 deletions

View File

@ -249,7 +249,7 @@ set( EESCHEMA_SRCS
netlist_exporters/netlist_exporter_cadstar.cpp
netlist_exporters/netlist_exporter_kicad.cpp
netlist_exporters/netlist_exporter_orcadpcb2.cpp
netlist_exporters/netlist_exporter_pspice.cpp
netlist_exporters/netlist_exporter_spice.cpp
netlist_exporters/netlist_exporter_xml.cpp
netlist_exporters/netlist_generator.cpp
@ -308,8 +308,8 @@ if( KICAD_SPICE )
dialogs/dialog_signal_list_base.cpp
dialogs/dialog_sim_settings.cpp
dialogs/dialog_sim_settings_base.cpp
dialogs/dialog_spice_model.cpp
dialogs/dialog_spice_model_base.cpp
dialogs/dialog_sim_model.cpp
dialogs/dialog_sim_model_base.cpp
sim/ngspice_helpers.cpp
sim/ngspice.cpp
sim/ngspice_models.cpp
@ -324,12 +324,12 @@ if( KICAD_SPICE )
sim/sim_library_spice.cpp
sim/sim_model.cpp
sim/sim_model_behavioral.cpp
sim/sim_model_codemodel.cpp
sim/sim_model_xspice.cpp
sim/sim_model_ideal.cpp
sim/sim_model_ngspice.cpp
sim/sim_model_rawspice.cpp
sim/sim_model_spice.cpp
sim/sim_model_source.cpp
sim/sim_model_subcircuit.cpp
sim/sim_model_subckt.cpp
sim/sim_value.cpp
sim/spice_simulator.cpp
sim/spice_value.cpp

View File

@ -35,7 +35,7 @@
#include <string_utils.h>
#ifdef KICAD_SPICE
#include <dialog_spice_model.h>
#include <dialog_sim_model.h>
#endif /* KICAD_SPICE */
#include <dialog_lib_symbol_properties.h>
@ -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_SIM_MODEL dialog( this, symbol, *m_fields );
if( dialog.ShowModal() != wxID_OK )
return;

View File

@ -42,7 +42,7 @@
#include <dialogs/dialog_netlist_base.h>
#include <wildcards_and_files_ext.h>
#include <invoke_sch_dialog.h>
#include <netlist_exporters/netlist_exporter_pspice.h>
#include <netlist_exporters/netlist_exporter_spice.h>
#include <eeschema_settings.h>
#include <schematic.h>
#include <paths.h>
@ -94,7 +94,8 @@ public:
NETLIST_TYPE_ID m_IdNetType;
// opt to reformat passive component values (e.g. 1M -> 1Meg):
wxCheckBox* m_AdjustPassiveValues;
wxCheckBox* m_SaveAllVoltages;
wxCheckBox* m_SaveAllCurrents;
wxTextCtrl* m_CommandStringCtrl;
wxTextCtrl* m_TitleStringCtrl;
wxBoxSizer* m_LeftBoxSizer;
@ -195,7 +196,8 @@ private:
/* Event id for notebook page buttons: */
enum id_netlist {
ID_CREATE_NETLIST = ID_END_EESCHEMA_ID_LIST + 1,
ID_USE_NETCODE_AS_NETNAME,
ID_SAVE_ALL_VOLTAGES,
ID_SAVE_ALL_CURRENTS,
ID_RUN_SIMULATOR
};
@ -214,7 +216,8 @@ NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook* parent, const wxString& ti
m_pageNetFmtName = title;
m_CommandStringCtrl = nullptr;
m_TitleStringCtrl = nullptr;
m_AdjustPassiveValues = nullptr;
m_SaveAllVoltages = nullptr;
m_SaveAllCurrents = nullptr;
parent->AddPage( this, title, false );
@ -289,7 +292,13 @@ void NETLIST_DIALOG::OnRunExternSpiceCommand( wxCommandEvent& event )
fn.SetExt( wxT( "cir" ) );
if( settings.m_SpiceAdjustPassiveValues )
netlist_opt |= NET_ADJUST_PASSIVE_VALS;
netlist_opt |= NETLIST_EXPORTER_SPICE::OPTION_ADJUST_PASSIVE_VALS;
if( settings.m_SpiceSaveAllVoltages )
netlist_opt |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES;
if( settings.m_SpiceSaveAllCurrents )
netlist_opt |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
// Build the command line
wxString commandLine = simulatorCommand;
@ -320,11 +329,18 @@ void NETLIST_DIALOG::InstallPageSpice()
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
page->m_AdjustPassiveValues = new wxCheckBox( page, ID_USE_NETCODE_AS_NETNAME,
_( "Reformat passive symbol values" ) );
page->m_AdjustPassiveValues->SetToolTip( _( "Reformat passive symbol values e.g. 1M -> 1Meg" ) );
page->m_AdjustPassiveValues->SetValue( settings.m_SpiceAdjustPassiveValues );
page->m_LeftBoxSizer->Add( page->m_AdjustPassiveValues, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
page->m_SaveAllVoltages = new wxCheckBox( page, ID_SAVE_ALL_VOLTAGES,
_( "Save all voltages" ) );
page->m_SaveAllVoltages->SetToolTip( _( "Write a directive to save all voltages (.save all)" ) );
page->m_SaveAllVoltages->SetValue( settings.m_SpiceSaveAllVoltages );
page->m_LeftBoxSizer->Add( page->m_SaveAllVoltages, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
page->m_SaveAllCurrents = new wxCheckBox( page, ID_SAVE_ALL_CURRENTS,
_( "Save all currents" ) );
page->m_SaveAllCurrents->SetToolTip( _( "Write a directive to save all currents (.probe alli)" ) );
page->m_SaveAllCurrents->SetValue( settings.m_SpiceSaveAllCurrents );
page->m_RightBoxSizer->Add( page->m_SaveAllCurrents, 0, wxGROW | wxBOTTOM | wxLEFT, 5 );
wxString simulatorCommand = settings.m_SpiceCommandString;
wxStaticText* spice_label = new wxStaticText( page, -1, _( "External simulator command:" ) );
@ -420,12 +436,14 @@ void NETLIST_DIALOG::OnNetlistTypeSelection( wxNotebookEvent& event )
void NETLIST_DIALOG::NetlistUpdateOpt()
{
bool adjust = m_PanelNetType[ PANELSPICE ]->m_AdjustPassiveValues->IsChecked();
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
wxString spice_cmd_string = m_PanelNetType[ PANELSPICE ]->m_CommandStringCtrl->GetValue();
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
settings.m_SpiceAdjustPassiveValues = adjust;
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
settings.m_SpiceCommandString = spice_cmd_string;
settings.m_NetFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
}
@ -454,8 +472,10 @@ bool NETLIST_DIALOG::TransferDataFromWindow()
{
case NET_TYPE_SPICE:
// Set spice netlist options:
if( currPage->m_AdjustPassiveValues->GetValue() )
netlist_opt |= NET_ADJUST_PASSIVE_VALS;
if( currPage->m_SaveAllVoltages->GetValue() )
netlist_opt |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES;
if( currPage->m_SaveAllCurrents->GetValue() )
netlist_opt |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
break;
case NET_TYPE_CADSTAR:

View File

@ -55,14 +55,14 @@ bool DIALOG_SIGNAL_LIST::TransferDataFromWindow()
bool DIALOG_SIGNAL_LIST::TransferDataToWindow()
{
// Create a list of possible signals
/// @todo it could include separated mag & phase for AC analysis
/// TODO: it could include separated mag & phase for AC analysis
if( m_circuitModel )
{
// Voltage list
for( const auto& net : m_circuitModel->GetNetIndexMap() )
for( const auto& net : m_circuitModel->GetNets() )
{
// netnames are escaped (can contain "{slash}" for '/') Unscape them:
wxString netname = UnescapeString( net.first );
wxString netname = UnescapeString( net );
if( netname != "GND" && netname != "0" )
m_signals->Append( wxString::Format( "V(%s)", netname ) );
@ -72,14 +72,11 @@ bool DIALOG_SIGNAL_LIST::TransferDataToWindow()
if( simType == ST_TRANSIENT || simType == ST_DC )
{
for( const auto& item : m_circuitModel->GetSpiceItems() )
for( const auto& item : m_circuitModel->GetItems() )
{
// Add all possible currents for the primitive
for( const auto& current :
NGSPICE_CIRCUIT_MODEL::GetCurrents( (SPICE_PRIMITIVE) item.m_primitive ) )
{
m_signals->Append( wxString::Format( "%s(%s)", current, item.m_refName ) );
}
// Add all possible currents for the primitive.
for( const auto& currentName : item.model->GenerateSpiceCurrentNames( item.refName ) )
m_signals->Append( currentName );
}
}
}
@ -104,22 +101,14 @@ bool DIALOG_SIGNAL_LIST::addSignalToPlotFrame( const wxString& aPlotName )
wxUniChar firstChar = aPlotName[0];
if( firstChar == 'V' || firstChar == 'v' )
{
m_plotFrame->AddVoltagePlot( name );
}
m_plotFrame->AddVoltagePlot( aPlotName );
else if( firstChar == 'I' || firstChar == 'i' )
{
m_plotFrame->AddCurrentPlot( name, aPlotName.BeforeFirst( '(' ) );
}
m_plotFrame->AddCurrentPlot( aPlotName );
else
{
return false;
}
}
else
{
return false;
}
return true;
}

View File

@ -22,7 +22,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <dialog_spice_model.h>
#include <dialog_sim_model.h>
#include <sim/sim_property.h>
#include <sim/sim_library_spice.h>
#include <widgets/wx_grid.h>
@ -31,39 +31,31 @@
#include <locale_io.h>
#include <wx/filedlg.h>
using TYPE = SIM_VALUE_BASE::TYPE;
using TYPE = SIM_VALUE::TYPE;
using CATEGORY = SIM_MODEL::PARAM::CATEGORY;
template class DIALOG_SPICE_MODEL<SCH_FIELD>;
template class DIALOG_SPICE_MODEL<LIB_FIELD>;
template class DIALOG_SIM_MODEL<SCH_FIELD>;
template class DIALOG_SIM_MODEL<LIB_FIELD>;
template <typename T>
DIALOG_SPICE_MODEL<T>::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
std::vector<T>& aFields )
: DIALOG_SPICE_MODEL_BASE( aParent ),
: DIALOG_SIM_MODEL_BASE( aParent ),
m_symbol( aSymbol ),
m_fields( aFields ),
m_library( std::make_shared<SIM_LIBRARY_SPICE>() ),
m_prevModel( nullptr ),
m_firstCategory( nullptr )
{
try
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
{
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
{
m_models.push_back( SIM_MODEL::Create( type, m_symbol.GetAllPins().size() ) );
m_models.push_back( SIM_MODEL::Create( type, m_symbol.GetAllPins().size() ) );
SIM_MODEL::DEVICE_TYPE deviceType = SIM_MODEL::TypeInfo( type ).deviceType;
if( !m_curModelTypeOfDeviceType.count( deviceType ) )
m_curModelTypeOfDeviceType[deviceType] = type;
}
}
catch( KI_PARAM_ERROR& e )
{
DisplayErrorMessage( this, e.What() );
return;
SIM_MODEL::DEVICE_TYPE deviceType = SIM_MODEL::TypeInfo( type ).deviceType;
if( !m_curModelTypeOfDeviceType.count( deviceType ) )
m_curModelTypeOfDeviceType[deviceType] = type;
}
@ -75,7 +67,7 @@ DIALOG_SPICE_MODEL<T>::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbo
m_scintillaTricks = std::make_unique<SCINTILLA_TRICKS>( m_codePreview, wxT( "{}" ), false );
m_paramGridMgr->Bind( wxEVT_PG_SELECTED, &DIALOG_SPICE_MODEL::onSelectionChange, this );
m_paramGridMgr->Bind( wxEVT_PG_SELECTED, &DIALOG_SIM_MODEL::onSelectionChange, this );
m_paramGrid->SetValidationFailureBehavior( wxPG_VFB_STAY_IN_PROPERTY
| wxPG_VFB_BEEP
@ -109,9 +101,10 @@ DIALOG_SPICE_MODEL<T>::DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbo
template <typename T>
bool DIALOG_SPICE_MODEL<T>::TransferDataToWindow()
bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
{
wxString libraryFilename = SIM_MODEL::GetFieldValue( &m_fields, LIBRARY_FIELD );
wxString libraryFilename = SIM_MODEL::GetFieldValue( &m_fields,
SIM_LIBRARY_SPICE::LIBRARY_FIELD );
if( !libraryFilename.IsEmpty() )
{
@ -119,9 +112,8 @@ bool DIALOG_SPICE_MODEL<T>::TransferDataToWindow()
loadLibrary( libraryFilename );
// Must be set before curModel() is used since the latter checks the combobox value.
m_modelNameCombobox->SetStringSelection( SIM_MODEL::GetFieldValue( &m_fields, NAME_FIELD ) );
curModel().ReadDataFields( m_symbol.GetAllPins().size(), &m_fields );
m_modelNameCombobox->SetStringSelection(
SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY_SPICE::NAME_FIELD ) );
m_overrideCheckbox->SetValue( curModel().HasNonPrincipalOverrides() );
}
@ -135,10 +127,10 @@ bool DIALOG_SPICE_MODEL<T>::TransferDataToWindow()
m_models.at( static_cast<int>( SIM_MODEL::ReadTypeFromFields( m_fields ) ) )
= SIM_MODEL::Create( m_symbol.GetAllPins().size(), m_fields );
}
catch( KI_PARAM_ERROR& e )
catch( const KI_PARAM_ERROR& e )
{
DisplayErrorMessage( this, e.What() );
return DIALOG_SPICE_MODEL_BASE::TransferDataToWindow();
return DIALOG_SIM_MODEL_BASE::TransferDataToWindow();
}
m_curModelType = type;
@ -146,20 +138,28 @@ bool DIALOG_SPICE_MODEL<T>::TransferDataToWindow()
updateWidgets();
return DIALOG_SPICE_MODEL_BASE::TransferDataToWindow();
return DIALOG_SIM_MODEL_BASE::TransferDataToWindow();
}
template <typename T>
bool DIALOG_SPICE_MODEL<T>::TransferDataFromWindow()
bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
{
if( !DIALOG_SPICE_MODEL_BASE::TransferDataFromWindow() )
if( !DIALOG_SIM_MODEL_BASE::TransferDataFromWindow() )
return false;
if( m_useLibraryModelRadioButton->GetValue() )
{
SIM_MODEL::SetFieldValue( m_fields, NAME_FIELD, m_modelNameCombobox->GetValue() );
SIM_MODEL::SetFieldValue( m_fields, LIBRARY_FIELD, m_library->GetFilename() );
SIM_MODEL::SetFieldValue( m_fields, SIM_LIBRARY_SPICE::NAME_FIELD,
m_modelNameCombobox->GetValue() );
wxString path = m_library->GetFilePath();
wxFileName fn( path );
if( fn.MakeRelativeTo( Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( ".." ) )
path = fn.GetFullPath();
SIM_MODEL::SetFieldValue( m_fields, SIM_LIBRARY_SPICE::LIBRARY_FIELD, path );
}
curModel().WriteFields( m_fields );
@ -169,7 +169,7 @@ bool DIALOG_SPICE_MODEL<T>::TransferDataFromWindow()
template <typename T>
void DIALOG_SPICE_MODEL<T>::updateWidgets()
void DIALOG_SIM_MODEL<T>::updateWidgets()
{
updateModelParamsTab();
updateModelCodeTab();
@ -180,7 +180,7 @@ void DIALOG_SPICE_MODEL<T>::updateWidgets()
template <typename T>
void DIALOG_SPICE_MODEL<T>::updateModelParamsTab()
void DIALOG_SIM_MODEL<T>::updateModelParamsTab()
{
if( &curModel() != m_prevModel )
{
@ -271,7 +271,7 @@ void DIALOG_SPICE_MODEL<T>::updateModelParamsTab()
template <typename T>
void DIALOG_SPICE_MODEL<T>::updateModelCodeTab()
void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
{
wxString modelName = m_modelNameCombobox->GetStringSelection();
@ -283,7 +283,7 @@ void DIALOG_SPICE_MODEL<T>::updateModelCodeTab()
template <typename T>
void DIALOG_SPICE_MODEL<T>::updatePinAssignmentsTab()
void DIALOG_SIM_MODEL<T>::updatePinAssignmentsTab()
{
if( &curModel() == m_prevModel )
return;
@ -332,7 +332,7 @@ void DIALOG_SPICE_MODEL<T>::updatePinAssignmentsTab()
template <typename T>
void DIALOG_SPICE_MODEL<T>::updatePinAssignmentsGridEditors()
void DIALOG_SIM_MODEL<T>::updatePinAssignmentsGridEditors()
{
wxString modelPinChoicesString = "";
bool isFirst = true;
@ -384,14 +384,15 @@ void DIALOG_SPICE_MODEL<T>::updatePinAssignmentsGridEditors()
template <typename T>
void DIALOG_SPICE_MODEL<T>::loadLibrary( const wxString& aFilePath )
void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aFilePath )
{
m_library->ReadFile( aFilePath );
m_libraryFilenameInput->SetValue( aFilePath );
m_library->ReadFile( Prj().AbsolutePath( aFilePath ) );
m_libraryPathInput->SetValue( aFilePath );
m_libraryModels.clear();
for( const SIM_MODEL& baseModel : m_library->GetModels() )
m_libraryModels.push_back( SIM_MODEL::Create( baseModel ) );
m_libraryModels.push_back( SIM_MODEL::Create( baseModel, m_symbol.GetAllPins().size(),
m_fields ) );
m_modelNameCombobox->Clear();
for( const wxString& name : m_library->GetModelNames() )
@ -402,7 +403,7 @@ void DIALOG_SPICE_MODEL<T>::loadLibrary( const wxString& aFilePath )
template <typename T>
void DIALOG_SPICE_MODEL<T>::addParamPropertyIfRelevant( int aParamIndex )
void DIALOG_SIM_MODEL<T>::addParamPropertyIfRelevant( int aParamIndex )
{
if( curModel().GetParam( aParamIndex ).info.dir == SIM_MODEL::PARAM::DIR::OUT )
return;
@ -465,24 +466,30 @@ void DIALOG_SPICE_MODEL<T>::addParamPropertyIfRelevant( int aParamIndex )
}
template <typename T>
wxPGProperty* DIALOG_SPICE_MODEL<T>::newParamProperty( int aParamIndex ) const
wxPGProperty* DIALOG_SIM_MODEL<T>::newParamProperty( int aParamIndex ) const
{
const SIM_MODEL::PARAM& param = curModel().GetParam( aParamIndex );
wxString paramDescription = wxString::Format( "%s (%s)",
param.info.description,
param.info.name );
wxString paramDescription;
if( !param.info.description.IsEmpty() )
paramDescription = wxString::Format( "%s (%s)",
param.info.description,
param.info.name );
else
paramDescription = wxString::Format( "%s", param.info.name );
wxPGProperty* prop = nullptr;
switch( param.info.type )
{
case TYPE::INT:
prop = new SIM_PROPERTY( paramDescription, param.info.name, m_library, curModelSharedPtr(),
aParamIndex, SIM_VALUE_BASE::TYPE::INT );
aParamIndex, SIM_VALUE::TYPE::INT );
break;
case TYPE::FLOAT:
prop = new SIM_PROPERTY( paramDescription, param.info.name, m_library, curModelSharedPtr(),
aParamIndex, SIM_VALUE_BASE::TYPE::FLOAT );
aParamIndex, SIM_VALUE::TYPE::FLOAT );
break;
case TYPE::BOOL:
@ -532,14 +539,14 @@ wxPGProperty* DIALOG_SPICE_MODEL<T>::newParamProperty( int aParamIndex ) const
template <typename T>
SIM_MODEL& DIALOG_SPICE_MODEL<T>::curModel() const
SIM_MODEL& DIALOG_SIM_MODEL<T>::curModel() const
{
return *curModelSharedPtr();
}
template <typename T>
std::shared_ptr<SIM_MODEL> DIALOG_SPICE_MODEL<T>::curModelSharedPtr() const
std::shared_ptr<SIM_MODEL> DIALOG_SIM_MODEL<T>::curModelSharedPtr() const
{
if( m_useLibraryModelRadioButton->GetValue()
&& m_modelNameCombobox->GetSelection() != wxNOT_FOUND )
@ -552,7 +559,7 @@ std::shared_ptr<SIM_MODEL> DIALOG_SPICE_MODEL<T>::curModelSharedPtr() const
template <typename T>
wxString DIALOG_SPICE_MODEL<T>::getSymbolPinString( int symbolPinNumber ) const
wxString DIALOG_SIM_MODEL<T>::getSymbolPinString( int symbolPinNumber ) const
{
wxString name = "";
SCH_PIN* symbolPin = m_symbol.GetAllPins().at( symbolPinNumber - 1 );
@ -570,7 +577,7 @@ wxString DIALOG_SPICE_MODEL<T>::getSymbolPinString( int symbolPinNumber ) const
template <typename T>
wxString DIALOG_SPICE_MODEL<T>::getModelPinString( int modelPinNumber ) const
wxString DIALOG_SIM_MODEL<T>::getModelPinString( int modelPinNumber ) const
{
const wxString& pinName = curModel().GetPin( modelPinNumber - 1 ).name;
@ -584,7 +591,7 @@ wxString DIALOG_SPICE_MODEL<T>::getModelPinString( int modelPinNumber ) const
template <typename T>
int DIALOG_SPICE_MODEL<T>::getModelPinNumber( const wxString& aModelPinString ) const
int DIALOG_SIM_MODEL<T>::getModelPinNumber( const wxString& aModelPinString ) const
{
if( aModelPinString == "Not Connected" )
return SIM_MODEL::PIN::NOT_CONNECTED;
@ -602,40 +609,46 @@ int DIALOG_SPICE_MODEL<T>::getModelPinNumber( const wxString& aModelPinString )
template <typename T>
void DIALOG_SPICE_MODEL<T>::onRadioButton( wxCommandEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onRadioButton( wxCommandEvent& aEvent )
{
updateWidgets();
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onBrowseButtonClick( wxCommandEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onBrowseButtonClick( wxCommandEvent& aEvent )
{
wxFileDialog dlg( this, _( "Browse Models" ) );
wxFileDialog dlg( this, _( "Browse Models" ), Prj().GetProjectPath() );
if( dlg.ShowModal() == wxID_CANCEL )
return;
loadLibrary( dlg.GetPath() );
wxString path = dlg.GetPath();
wxFileName fn( path );
if( fn.MakeRelativeTo( Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( ".." ) )
path = fn.GetFullPath();
loadLibrary( path );
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onModelNameCombobox( wxCommandEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onModelNameCombobox( wxCommandEvent& aEvent )
{
updateWidgets();
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onOverrideCheckbox( wxCommandEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onOverrideCheckbox( wxCommandEvent& aEvent )
{
updateWidgets();
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent )
{
SIM_MODEL::DEVICE_TYPE deviceType =
static_cast<SIM_MODEL::DEVICE_TYPE>( m_deviceTypeChoice->GetSelection() );
@ -647,7 +660,7 @@ void DIALOG_SPICE_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent )
template <typename T>
void DIALOG_SPICE_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
{
SIM_MODEL::DEVICE_TYPE deviceType =
static_cast<SIM_MODEL::DEVICE_TYPE>( m_deviceTypeChoice->GetSelection() );
@ -669,14 +682,14 @@ void DIALOG_SPICE_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
template <typename T>
void DIALOG_SPICE_MODEL<T>::onParamGridChanged( wxPropertyGridEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onParamGridChanged( wxPropertyGridEvent& aEvent )
{
updateWidgets();
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent )
{
int symbolPinNumber = aEvent.GetRow() + 1;
int oldModelPinNumber = getModelPinNumber( aEvent.GetString() );
@ -696,7 +709,7 @@ void DIALOG_SPICE_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent
template <typename T>
void DIALOG_SPICE_MODEL<T>::onPinAssignmentsGridSize( wxSizeEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onPinAssignmentsGridSize( wxSizeEvent& aEvent )
{
wxGridUpdateLocker deferRepaintsTillLeavingScope( m_pinAssignmentsGrid );
@ -709,49 +722,49 @@ void DIALOG_SPICE_MODEL<T>::onPinAssignmentsGridSize( wxSizeEvent& aEvent )
template <typename T>
void DIALOG_SPICE_MODEL<T>::onLibraryFilenameInputUpdate( wxUpdateUIEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onLibraryFilenameInputUpdate( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( m_useLibraryModelRadioButton->GetValue() );
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onBrowseButtonUpdate( wxUpdateUIEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onBrowseButtonUpdate( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( m_useLibraryModelRadioButton->GetValue() );
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onModelNameComboboxUpdate( wxUpdateUIEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onModelNameComboboxUpdate( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( m_useLibraryModelRadioButton->GetValue() );
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onOverrideCheckboxUpdate( wxUpdateUIEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onOverrideCheckboxUpdate( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( m_useLibraryModelRadioButton->GetValue() );
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onDeviceTypeChoiceUpdate( wxUpdateUIEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onDeviceTypeChoiceUpdate( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( m_useInstanceModelRadioButton->GetValue() );
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onTypeChoiceUpdate( wxUpdateUIEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onTypeChoiceUpdate( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( m_useInstanceModelRadioButton->GetValue() );
}
template <typename T>
void DIALOG_SPICE_MODEL<T>::onSelectionChange( wxPropertyGridEvent& aEvent )
void DIALOG_SIM_MODEL<T>::onSelectionChange( wxPropertyGridEvent& aEvent )
{
// TODO: Activate also when the whole property grid is selected with tab key.

View File

@ -25,8 +25,8 @@
#ifndef DIALOG_SPICE_MODEL_H
#define DIALOG_SPICE_MODEL_H
#include <dialog_spice_model_base.h>
#include <netlist_exporter_pspice.h>
#include <dialog_sim_model_base.h>
#include <netlist_exporter_spice.h>
#include <scintilla_tricks.h>
#include <sim/sim_model.h>
@ -39,16 +39,13 @@
// 2. wxPropertyGridManager->ShowHeader() segfaults when called from this dialog's constructor.
template <typename T>
class DIALOG_SPICE_MODEL : public DIALOG_SPICE_MODEL_BASE
class DIALOG_SIM_MODEL : public DIALOG_SIM_MODEL_BASE
{
public:
static constexpr auto LIBRARY_FIELD = "Model_Library";
static constexpr auto NAME_FIELD = "Model_Name";
enum class PARAM_COLUMN : int { DESCRIPTION, VALUE, UNIT, DEFAULT, TYPE, END_ };
enum class PIN_COLUMN : int { SYMBOL, MODEL };
DIALOG_SPICE_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol, std::vector<T>& aSchFields );
DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol, std::vector<T>& aSchFields );
private:
bool TransferDataToWindow() override;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1)
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -7,11 +7,11 @@
#include "widgets/wx_grid.h"
#include "dialog_spice_model_base.h"
#include "dialog_sim_model_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
@ -38,8 +38,8 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
m_useLibraryModelRadioButton = new wxRadioButton( sbSizer4->GetStaticBox(), wxID_ANY, wxT("Library:"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer15->Add( m_useLibraryModelRadioButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_libraryFilenameInput = new wxTextCtrl( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer15->Add( m_libraryFilenameInput, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
m_libraryPathInput = new wxTextCtrl( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer15->Add( m_libraryPathInput, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
m_browseButton = new wxBitmapButton( sbSizer4->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
fgSizer15->Add( m_browseButton, 0, wxALL, 5 );
@ -230,42 +230,42 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
this->Centre( wxBOTH );
// Connect Events
m_useInstanceModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onRadioButton ), NULL, this );
m_useLibraryModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onRadioButton ), NULL, this );
m_libraryFilenameInput->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onLibraryFilenameInputUpdate ), NULL, this );
m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onBrowseButtonClick ), NULL, this );
m_browseButton->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
m_modelNameCombobox->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onModelNameCombobox ), NULL, this );
m_modelNameCombobox->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this );
m_overrideCheckbox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onOverrideCheckbox ), NULL, this );
m_overrideCheckbox->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onOverrideCheckboxUpdate ), NULL, this );
m_deviceTypeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoice ), NULL, this );
m_deviceTypeChoice->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoiceUpdate ), NULL, this );
m_typeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoice ), NULL, this );
m_typeChoice->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoiceUpdate ), NULL, this );
m_paramGridMgr->Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SPICE_MODEL_BASE::onParamGridChanged ), NULL, this );
m_pinAssignmentsGrid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SPICE_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
m_pinAssignmentsGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SPICE_MODEL_BASE::onPinAssignmentsGridSize ), NULL, this );
m_useInstanceModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
m_useLibraryModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
m_libraryPathInput->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryFilenameInputUpdate ), NULL, this );
m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonClick ), NULL, this );
m_browseButton->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
m_modelNameCombobox->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameCombobox ), NULL, this );
m_modelNameCombobox->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this );
m_overrideCheckbox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onOverrideCheckbox ), NULL, this );
m_overrideCheckbox->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onOverrideCheckboxUpdate ), NULL, this );
m_deviceTypeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onDeviceTypeChoice ), NULL, this );
m_deviceTypeChoice->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onDeviceTypeChoiceUpdate ), NULL, this );
m_typeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onTypeChoice ), NULL, this );
m_typeChoice->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onTypeChoiceUpdate ), NULL, this );
m_paramGridMgr->Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SIM_MODEL_BASE::onParamGridChanged ), NULL, this );
m_pinAssignmentsGrid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
m_pinAssignmentsGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridSize ), NULL, this );
}
DIALOG_SPICE_MODEL_BASE::~DIALOG_SPICE_MODEL_BASE()
DIALOG_SIM_MODEL_BASE::~DIALOG_SIM_MODEL_BASE()
{
// Disconnect Events
m_useInstanceModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onRadioButton ), NULL, this );
m_useLibraryModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onRadioButton ), NULL, this );
m_libraryFilenameInput->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onLibraryFilenameInputUpdate ), NULL, this );
m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onBrowseButtonClick ), NULL, this );
m_browseButton->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
m_modelNameCombobox->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onModelNameCombobox ), NULL, this );
m_modelNameCombobox->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this );
m_overrideCheckbox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onOverrideCheckbox ), NULL, this );
m_overrideCheckbox->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onOverrideCheckboxUpdate ), NULL, this );
m_deviceTypeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoice ), NULL, this );
m_deviceTypeChoice->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onDeviceTypeChoiceUpdate ), NULL, this );
m_typeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoice ), NULL, this );
m_typeChoice->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SPICE_MODEL_BASE::onTypeChoiceUpdate ), NULL, this );
m_paramGridMgr->Disconnect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SPICE_MODEL_BASE::onParamGridChanged ), NULL, this );
m_pinAssignmentsGrid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SPICE_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
m_pinAssignmentsGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SPICE_MODEL_BASE::onPinAssignmentsGridSize ), NULL, this );
m_useInstanceModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
m_useLibraryModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
m_libraryPathInput->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryFilenameInputUpdate ), NULL, this );
m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonClick ), NULL, this );
m_browseButton->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
m_modelNameCombobox->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameCombobox ), NULL, this );
m_modelNameCombobox->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this );
m_overrideCheckbox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onOverrideCheckbox ), NULL, this );
m_overrideCheckbox->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onOverrideCheckboxUpdate ), NULL, this );
m_deviceTypeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onDeviceTypeChoice ), NULL, this );
m_deviceTypeChoice->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onDeviceTypeChoiceUpdate ), NULL, this );
m_typeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onTypeChoice ), NULL, this );
m_typeChoice->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onTypeChoiceUpdate ), NULL, this );
m_paramGridMgr->Disconnect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( DIALOG_SIM_MODEL_BASE::onParamGridChanged ), NULL, this );
m_pinAssignmentsGrid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridCellChange ), NULL, this );
m_pinAssignmentsGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SIM_MODEL_BASE::onPinAssignmentsGridSize ), NULL, this );
}

View File

@ -11,13 +11,13 @@
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">dialog_spice_model_base</property>
<property name="file">dialog_sim_model_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">0</property>
<property name="name">DIALOG_SPICE_MODEL_BASE</property>
<property name="name">DIALOG_SIM_MODEL_BASE</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
@ -45,11 +45,11 @@
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">DIALOG_SPICE_MODEL_BASE</property>
<property name="name">DIALOG_SIM_MODEL_BASE</property>
<property name="pos"></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="subclass">DIALOG_SHIM; dialog_shim.h; forward_declare</property>
<property name="title">Spice Model Editor</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
@ -376,7 +376,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_libraryFilenameInput</property>
<property name="name">m_libraryPathInput</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1)
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -11,6 +11,7 @@
#include <wx/xrc/xmlres.h>
class WX_GRID;
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/radiobut.h>
#include <wx/gdicmn.h>
@ -43,9 +44,9 @@ class WX_GRID;
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_SPICE_MODEL_BASE
/// Class DIALOG_SIM_MODEL_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_SPICE_MODEL_BASE : public wxDialog
class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
{
private:
@ -54,7 +55,7 @@ class DIALOG_SPICE_MODEL_BASE : public wxDialog
wxPanel* m_modelPanel;
wxRadioButton* m_useInstanceModelRadioButton;
wxRadioButton* m_useLibraryModelRadioButton;
wxTextCtrl* m_libraryFilenameInput;
wxTextCtrl* m_libraryPathInput;
wxBitmapButton* m_browseButton;
wxStaticText* m_modelNameLabel;
wxComboBox* m_modelNameCombobox;
@ -97,9 +98,9 @@ class DIALOG_SPICE_MODEL_BASE : public wxDialog
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 = wxSize( 600,800 ), long style = wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP );
DIALOG_SIM_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();
~DIALOG_SIM_MODEL_BASE();
};

View File

@ -133,7 +133,7 @@ wxString DIALOG_SIM_SETTINGS::evaluateDCControls( wxChoice* aDcSource, wxTextCtr
{
// pick device name from exporter when something different than temperature is selected
if( dcSource.Cmp( "TEMP" ) )
dcSource = m_circuitModel->GetSpiceDevice( dcSource );
dcSource = m_circuitModel->GetItemName( dcSource );
return wxString::Format( "%s %s %s %s", dcSource,
SPICE_VALUE( aDcStart->GetValue() ).ToSpiceString(),
@ -224,7 +224,7 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
}
else if( page == m_pgNoise ) // Noise analysis
{
const std::map<wxString, int>& netMap = m_circuitModel->GetNetIndexMap();
/*const std::map<wxString, int>& netMap = m_circuitModel->GetNetIndexMap();
if( empty( m_noiseMeas ) || empty( m_noiseSrc ) || empty( m_noisePointsNumber )
|| empty( m_noiseFreqStart ) || empty( m_noiseFreqStop ) )
@ -248,7 +248,7 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
noiseSource, scaleToString( m_noiseScale->GetSelection() ),
m_noisePointsNumber->GetValue(),
SPICE_VALUE( m_noiseFreqStart->GetValue() ).ToSpiceString(),
SPICE_VALUE( m_noiseFreqStop->GetValue() ).ToSpiceString() );
SPICE_VALUE( m_noiseFreqStop->GetValue() ).ToSpiceString() );*/
}
else if( page == m_pgOP ) // DC operating point analysis
{
@ -300,8 +300,8 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
updateNetlistOpts();
m_settings->SetFixPassiveVals( m_netlistOpts & NET_ADJUST_PASSIVE_VALS );
m_settings->SetFixIncludePaths( m_netlistOpts & NET_ADJUST_INCLUDE_PATHS );
m_settings->SetFixPassiveVals( m_netlistOpts & NETLIST_EXPORTER_SPICE::OPTION_ADJUST_PASSIVE_VALS );
m_settings->SetFixIncludePaths( m_netlistOpts & NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS );
return true;
}
@ -368,10 +368,10 @@ int DIALOG_SIM_SETTINGS::ShowModal()
for( auto c : cmbNet )
c.first->Clear();
for( const auto& net : m_circuitModel->GetNetIndexMap() )
for( const auto& net : m_circuitModel->GetNets() )
{
for( auto c : cmbNet )
c.first->Append( net.first );
c.first->Append( net );
}
// Try to restore the previous selection, if possible
@ -399,10 +399,15 @@ void DIALOG_SIM_SETTINGS::updateDCSources( wxChar aType, wxChoice* aSource )
if( aType != 'T' )
{
for( const auto& item : m_circuitModel->GetSpiceItems() )
for( const auto& item : m_circuitModel->GetItems() )
{
if( item.m_primitive == aType && !item.m_refName.IsEmpty() )
sourcesList.insert( item.m_refName );
if( ( aType == 'R' && item.model->GetDeviceType() == SIM_MODEL::DEVICE_TYPE::R )
|| ( aType == 'C' && item.model->GetDeviceType() == SIM_MODEL::DEVICE_TYPE::C )
|| ( aType == 'L' && item.model->GetDeviceType() == SIM_MODEL::DEVICE_TYPE::L ) )
{
// TODO: VSOURCE, ISOURCE.
sourcesList.insert( item.refName );
}
}
if( aSource == m_dcSource2 && !m_dcEnable2->IsChecked() )
@ -606,11 +611,11 @@ void DIALOG_SIM_SETTINGS::loadDirectives()
void DIALOG_SIM_SETTINGS::updateNetlistOpts()
{
m_netlistOpts = NET_ALL_FLAGS;
m_netlistOpts = NETLIST_EXPORTER_SPICE::OPTION_ALL_FLAGS;
if( !m_fixPassiveVals->IsChecked() )
m_netlistOpts &= ~NET_ADJUST_PASSIVE_VALS;
m_netlistOpts &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_PASSIVE_VALS;
if( !m_fixIncludePaths->IsChecked() )
m_netlistOpts &= ~NET_ADJUST_INCLUDE_PATHS;
m_netlistOpts &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
}

View File

@ -49,7 +49,7 @@
#include <math/vector2d.h>
#ifdef KICAD_SPICE
#include <dialog_spice_model.h>
#include <dialog_sim_model.h>
#endif /* KICAD_SPICE */
@ -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_SIM_MODEL dialog( this, *m_symbol, *m_fields );
if( dialog.ShowModal() != wxID_OK )
return;

View File

@ -1,235 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2013 jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2021 KiCad Developers
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef NETLIST_EXPORTER_PSPICE_H
#define NETLIST_EXPORTER_PSPICE_H
#include "netlist_exporter_base.h"
#include <list>
#include <map>
class PROJECT;
/// Flags for Spice netlist generation (can be combined)
enum SPICE_NETLIST_OPTIONS {
NET_ADJUST_INCLUDE_PATHS = 8, // use full paths for included files (if they are in search path)
NET_ADJUST_PASSIVE_VALS = 16, // reformat passive symbol values (e.g. 1M -> 1Meg)
NET_ALL_FLAGS = 0xffff
};
enum SPICE_FIELD {
SF_PRIMITIVE,
SF_MODEL,
SF_ENABLED,
SF_NODE_SEQUENCE,
SF_LIB_FILE,
SF_END // sentinel
};
///< Basic Spice component primitives
enum SPICE_PRIMITIVE {
SP_UNKNOWN = ' ',
SP_RESISTOR = 'R',
SP_CAPACITOR = 'C',
SP_INDUCTOR = 'L',
SP_TLINE = 'T',
SP_TLINE_LOSSY = 'O',
SP_DIODE = 'D',
SP_BJT = 'Q',
SP_MOSFET = 'M',
SP_JFET = 'J',
SP_SUBCKT = 'X',
SP_CODEMODEL = 'A',
SP_VSOURCE = 'V',
SP_ISOURCE = 'I'
};
/// @todo add NET_ADJUST_INCLUDE_PATHS & NET_ADJUST_PASSIVE_VALS checkboxes in the netlist
/// export dialog.
/**
* Structure to represent a schematic symbol in the Spice simulation.
*/
struct SPICE_ITEM
{
SCH_SYMBOL* m_parent; ///< Schematic symbol represented by this SPICE_ITEM.
wxChar m_primitive; ///< Spice primitive type (@see SPICE_PRIMITIVE).
wxString m_model; ///< Library model (for semiconductors and subcircuits),
///< component value (for passive components) or
///< voltage/current (for sources).
wxString m_refName;
bool m_enabled; ///< Whether the symbol should be used in simulation.
std::vector<wxString> m_pins; ///< Array containing Standard Pin Name
std::vector<int> m_pinSequence; ///< Numeric indices into m_SortedSymbolPinList
};
/**
* Generate a PSPICE compatible netlist.
*/
class NETLIST_EXPORTER_PSPICE : public NETLIST_EXPORTER_BASE
{
public:
NETLIST_EXPORTER_PSPICE( SCHEMATIC_IFACE* aSchematic ) :
NETLIST_EXPORTER_BASE( aSchematic )
{
}
virtual ~NETLIST_EXPORTER_PSPICE()
{
}
/**
* Return list of items representing schematic components in the Spice world.
*/
const std::list<SPICE_ITEM>& GetSpiceItems() const
{
return m_spiceItems;
}
/**
* Return name of Spice device corresponding to a schematic symbol.
*
* @param aSymbol is the component reference.
* @return Spice device name or empty string if there is no such symbol in the netlist. The
* name is either plain reference if the first character of reference corresponds to the
* assigned device model type or it is the reference prefixed with a character defining
* the device model type.
*/
wxString GetSpiceDevice( const wxString& aSymbol ) const;
/**
* @brief Returns the command to alter a Spice parameter of a schematic symbol.
*
* @param aSymbol is the symbol reference.
* @return Spice command or empty string if there is no such component in the netlist,
* and true if it is a code model parameter, false if it is an instance parameter.
*/
std::pair<wxString, bool> GetSpiceTuningCommand( const wxString& aSymbol ) const;
/**
* Write to specified output file
*/
bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions ) override;
///< @copydoc NETLIST_EXPORTER_BASE::Format()
bool Format( OUTPUTFORMATTER* aFormatter, unsigned aCtl );
/**
* Process the netlist to create net mapping and a list of SPICE_ITEMs.
* It is automatically called by WriteNetlist(), but might be used separately,
* if only net mapping and the list of SPICE_ITEMs are required.
* @return True if successful.
*/
bool ProcessNetlist( unsigned aCtl );
/**
* Replace illegal spice net name characters with an underscore.
*/
static void ReplaceForbiddenChars( wxString& aNetName );
/**
* Return a map of circuit nodes to net names.
*/
const std::map<wxString, int>& GetNetIndexMap() const
{
return m_netMap;
}
/**
* Return a vector of component field names related to Spice simulation.
*/
static const std::vector<wxString>& GetSpiceFields()
{
return m_spiceFields;
}
/**
* Return a string used for a particular component field related to Spice simulation.
*/
static const wxString& GetSpiceFieldName( SPICE_FIELD aField )
{
return m_spiceFields[(int) aField];
}
/**
* Retrieve either the requested field value or the default value.
*/
static wxString GetSpiceField( SPICE_FIELD aField, SCH_SYMBOL* aSymbol, unsigned aCtl );
/**
* Retrieve the default value for a given field.
*/
static wxString GetSpiceFieldDefVal( SPICE_FIELD aField, SCH_SYMBOL* aSymbol, unsigned aCtl );
/**
* Update the vector of Spice directives placed in the schematics.
*/
void UpdateDirectives( unsigned aCtl );
/**
* Return a vector of Spice directives found in the schematics.
*/
const std::vector<wxString> GetDirectives() const
{
return m_directives;
}
/**
* Convert typical boolean string values (no/yes, true/false, 1/0) to a boolean value.
*/
static bool StringToBool( const wxString& aStr )
{
if( aStr.IsEmpty() )
return false;
char c = tolower( aStr[0] );
// Different ways of saying false (no/false/0)
return !( c == 'n' || c == 'f' || c == '0' );
}
protected:
/**
* Save the Spice directives.
*/
virtual void writeDirectives( OUTPUTFORMATTER* aFormatter, unsigned aCtl ) const;
private:
wxString m_title; ///< Spice simulation title found in the schematic sheet
std::vector<wxString> m_directives; ///< Spice directives found in the schematic sheet
std::set<wxString> m_libraries; ///< Spice libraries used by the simulated circuit
std::map<wxString, int> m_netMap; ///< Map spice nodes to net codes
std::list<SPICE_ITEM> m_spiceItems; ///< Items representing schematic symbols in Spice world
// Component fields that are processed during netlist export & simulation
static const std::vector<wxString> m_spiceFields;
};
#endif

View File

@ -0,0 +1,364 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2013 jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-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 "netlist_exporter_spice.h"
#include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp>
#include <common.h>
#include <confirm.h>
#include <pgm_base.h>
#include <env_paths.h>
#include <sim/sim_library.h>
#include <sch_screen.h>
#include <sch_text.h>
#include <sch_textbox.h>
#include <string_utils.h>
namespace NETLIST_EXPORTER_SPICE_PARSER
{
using namespace SPICE_GRAMMAR;
struct textGrammar : spiceSourceGrammar {};
template <typename Rule> struct textSelector : std::false_type {};
template <> struct textSelector<modelUnit> : std::true_type {};
template <> struct textSelector<dotTitle> : std::true_type {};
template <> struct textSelector<dotTitleTitle> : std::true_type {};
template <> struct textSelector<dotInclude> : std::true_type {};
template <> struct textSelector<dotIncludePathWithoutQuotes> : std::true_type {};
template <> struct textSelector<dotIncludePathWithoutApostrophes> : std::true_type {};
template <> struct textSelector<dotIncludePath> : std::true_type {};
template <> struct textSelector<dotLine> : std::true_type {};
}
bool NETLIST_EXPORTER_SPICE::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
{
FILE_OUTPUTFORMATTER formatter( aOutFileName, wxT( "wt" ), '\'' );
return GenerateNetlist( formatter, aNetlistOptions );
}
bool NETLIST_EXPORTER_SPICE::GenerateNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
{
// Default title.
m_title = "KiCad schematic";
if( !ReadSchematicAndLibraries( aNetlistOptions ) )
return false;
aFormatter.Print( 0, ".title %s\n", TO_UTF8( m_title ) );
writeIncludes( aFormatter, aNetlistOptions );
writeModels( aFormatter );
writeDirectives( aFormatter, aNetlistOptions );
writeItems( aFormatter );
aFormatter.Print( 0, ".end\n" );
return true;
}
bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions )
{
std::set<wxString> refNames; // Set of reference names to check for duplication.
int notConnectedCounter = 1;
ReadDirectives();
m_nets.clear();
m_items.clear();
for( unsigned int sheetIndex = 0; sheetIndex < m_schematic->GetSheets().size(); ++sheetIndex )
{
SCH_SHEET_PATH sheet = m_schematic->GetSheets().at( sheetIndex );
for( SCH_ITEM* schItem : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
{
SCH_SYMBOL* symbol = findNextSymbol( schItem, &sheet );
if( !symbol )
continue;
CreatePinList( symbol, &sheet, true );
SPICE_ITEM item;
item.model = SIM_MODEL::Create(
static_cast<int>( m_sortedSymbolPinList.size() ), symbol->GetFields() );
readLibraryField( *symbol, item );
readNameField( *symbol, item );
readEnabledField( *symbol, item );
if( !readRefName( sheet, *symbol, item, refNames ) )
return false;
readPins( *symbol, item, notConnectedCounter );
// TODO: transmission line handling?
m_items.push_back( std::move( item ) );
}
}
return true;
}
void NETLIST_EXPORTER_SPICE::ReplaceForbiddenChars( wxString& aNetName )
{
aNetName.Replace( "(", "_" );
aNetName.Replace( ")", "_" );
aNetName.Replace( " ", "_" );
}
wxString NETLIST_EXPORTER_SPICE::GetItemName( const wxString& aRefName ) const
{
const std::list<SPICE_ITEM>& spiceItems = GetItems();
auto it = std::find_if( spiceItems.begin(), spiceItems.end(),
[aRefName]( const SPICE_ITEM& aItem )
{
return aItem.refName == aRefName;
} );
if( it == spiceItems.end() )
return "";
return it->model->GenerateSpiceItemName( aRefName );
}
void NETLIST_EXPORTER_SPICE::ReadDirectives()
{
m_directives.clear();
for( unsigned int sheetIndex = 0; sheetIndex < m_schematic->GetSheets().size(); ++sheetIndex )
{
for( SCH_ITEM* item : m_schematic->GetSheets().at( sheetIndex ).LastScreen()->Items() )
{
wxString text;
if( item->Type() == SCH_TEXT_T )
text = static_cast<SCH_TEXT*>( item )->GetShownText();
else if( item->Type() == SCH_TEXTBOX_T )
text = static_cast<SCH_TEXTBOX*>( item )->GetShownText();
else
continue;
tao::pegtl::string_input<> in( text.ToStdString()+"\n", "from_content" );
std::unique_ptr<tao::pegtl::parse_tree::node> root;
try
{
root = tao::pegtl::parse_tree::parse<NETLIST_EXPORTER_SPICE_PARSER::textGrammar,
NETLIST_EXPORTER_SPICE_PARSER::textSelector>
( in );
}
catch( const tao::pegtl::parse_error& e )
{
continue;
}
wxASSERT( root );
for( const auto& node : root->children )
{
if( node->is_type<NETLIST_EXPORTER_SPICE_PARSER::dotTitle>() )
m_title = node->children.at( 0 )->string();
else if( node->is_type<NETLIST_EXPORTER_SPICE_PARSER::dotInclude>() )
m_libraries[node->children.at( 0 )->string()] =
SIM_LIBRARY::Create( node->children.at( 0 )->string() );
else
m_directives.emplace_back( node->string() );
}
}
}
}
void NETLIST_EXPORTER_SPICE::readLibraryField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
{
SCH_FIELD* field = aSymbol.FindField( SIM_LIBRARY::LIBRARY_FIELD );
if( !field )
return;
wxString path = field->GetShownText();
if( auto library = SIM_LIBRARY::Create( m_schematic->Prj().AbsolutePath( path ) ) )
m_libraries.try_emplace( path, std::move( library ) );
aItem.libraryPath = path;
}
void NETLIST_EXPORTER_SPICE::readNameField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
{
SCH_FIELD* field = aSymbol.FindField( SIM_LIBRARY::NAME_FIELD );
if( !field )
return;
wxString modelName = field->GetShownText();
if( m_libraries.count( aItem.libraryPath ) )
{
const SIM_LIBRARY& library = *m_libraries.at( aItem.libraryPath );
const SIM_MODEL* baseModel = library.FindModel( modelName );
if( baseModel )
{
aItem.model = SIM_MODEL::Create( *baseModel,
static_cast<int>( m_sortedSymbolPinList.size() ),
aSymbol.GetFields() );
aItem.modelName = modelName;
return;
}
}
}
void NETLIST_EXPORTER_SPICE::readEnabledField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
{
SCH_FIELD* field = aSymbol.FindField( ENABLED_FIELD );
if( !field )
return;
aItem.enabled = StringToBool( field->GetShownText() );
}
bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol,
SPICE_ITEM& aItem,
std::set<wxString>& aRefNames )
{
aItem.refName = aSymbol.GetRef( &aSheet );
if( aRefNames.count( aItem.refName ) )
{
DisplayErrorMessage( nullptr,
_( "Multiple symbols have the same reference designator.\n"
"Annotation must be corrected before simulating." ) );
return false;
}
aRefNames.insert( aItem.refName );
return true;
}
void NETLIST_EXPORTER_SPICE::readPins( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
int& notConnectedCounter )
{
for( const PIN_INFO& pin : m_sortedSymbolPinList )
{
wxString netName = pin.netName;
ReplaceForbiddenChars( netName );
netName = UnescapeString( netName );
if( netName.IsEmpty() )
netName = wxString::Format( wxT( "NC_%.2u" ), notConnectedCounter++ );
aItem.pins.push_back( netName );
m_nets.insert( netName );
}
}
void NETLIST_EXPORTER_SPICE::writeIncludes( OUTPUTFORMATTER& aFormatter,
unsigned aNetlistOptions )
{
for( auto&& [libraryPath, library] : m_libraries )
{
// First, expand env vars, if any.
wxString libName = ExpandEnvVarSubstitutions( libraryPath, &m_schematic->Prj() );
wxString fullPath;
if( aNetlistOptions & OPTION_ADJUST_INCLUDE_PATHS )
{
// Look for the library in known search locations.
fullPath = ResolveFile( libName, &Pgm().GetLocalEnvVariables(), &m_schematic->Prj() );
if( fullPath.IsEmpty() )
{
DisplayErrorMessage( nullptr,
wxString::Format( _( "Could not find library file '%s'" ), libName ) );
fullPath = libName;
}
}
else
fullPath = libName;
aFormatter.Print( 0, ".include \"%s\"\n", TO_UTF8( fullPath ) );
}
}
void NETLIST_EXPORTER_SPICE::writeModels( OUTPUTFORMATTER& aFormatter )
{
for( const SPICE_ITEM& item : m_items )
{
if( !item.enabled )
continue;
aFormatter.Print( 0, "%s", TO_UTF8( item.model->GenerateSpiceModelLine( item.modelName ) ) );
}
}
void NETLIST_EXPORTER_SPICE::writeItems( OUTPUTFORMATTER& aFormatter )
{
for( const SPICE_ITEM& item : m_items )
{
if( !item.enabled )
continue;
aFormatter.Print( 0, "%s", TO_UTF8( item.model->GenerateSpiceItemLine( item.refName,
item.modelName,
item.pins ) ) );
}
}
void NETLIST_EXPORTER_SPICE::writeDirectives( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
{
if( aNetlistOptions & OPTION_SAVE_ALL_VOLTAGES )
aFormatter.Print( 0, ".save all\n" );
if( aNetlistOptions & OPTION_SAVE_ALL_CURRENTS )
aFormatter.Print( 0, ".probe alli\n" );
for( const wxString& directive : m_directives )
aFormatter.Print( 0, "%s\n", TO_UTF8( directive ) );
}

View File

@ -0,0 +1,145 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2013 jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2021 KiCad Developers
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef NETLIST_EXPORTER_PSPICE_H
#define NETLIST_EXPORTER_PSPICE_H
#include "netlist_exporter_base.h"
#include <sim/sim_model.h>
#include <sim/sim_library.h>
struct SPICE_ITEM
{
wxString refName;
wxString libraryPath;
bool enabled;
std::vector<wxString> pins;
std::unique_ptr<const SIM_MODEL> model;
wxString modelName;
};
class NETLIST_EXPORTER_SPICE : public NETLIST_EXPORTER_BASE
{
public:
static constexpr auto ENABLED_FIELD = "Model_Enabled";
enum OPTIONS
{
OPTION_ADJUST_INCLUDE_PATHS = 8,
OPTION_ADJUST_PASSIVE_VALS = 16,
OPTION_SAVE_ALL_VOLTAGES = 16,
OPTION_SAVE_ALL_CURRENTS = 32,
OPTION_ALL_FLAGS = 0xFFFF
};
NETLIST_EXPORTER_SPICE( SCHEMATIC_IFACE* aSchematic ) : NETLIST_EXPORTER_BASE( aSchematic ) {}
/**
* Write to specified output file.
*/
bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions ) override;
/**
* Generate the netlist in aFormatter.
*/
bool GenerateNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions );
/**
* Process the schematic and Spice libraries to create net mapping and a list of SPICE_ITEMs.
* It is automatically called by WriteNetlist(), but might be used separately,
* if only net mapping and the list of SPICE_ITEMs are required.
* @return True if successful.
*/
bool ReadSchematicAndLibraries( unsigned aNetlistOptions );
/**
* Replace illegal spice net name characters with underscores.
*/
static void ReplaceForbiddenChars( wxString& aNetName );
/**
* Return the list of nets.
*/
const std::set<wxString>& GetNets() const { return m_nets; }
/**
* Return name of Spice device corresponding to a schematic symbol.
*
* @param aRefName is the component reference.
* @return Spice device name or empty string if there is no such symbol in the netlist.
* Normally the name is either plain reference if the first character of reference corresponds
* to the assigned device model type or it is the reference prefixed with a character defining
* the device model type.
*/
wxString GetItemName( const wxString& aRefName ) const;
/**
* Return the list of items representing schematic components in the Spice world.
*/
const std::list<SPICE_ITEM>& GetItems() const { return m_items; }
/**
* Convert typical boolean string values (no/yes, true/false, 1/0) to a boolean value.
*/
static bool StringToBool( const wxString& aStr )
{
if( aStr.IsEmpty() )
return false;
char c = aStr.Lower()[0];
// Different ways of saying false (no/false/0)
return !( c == 'n' || c == 'f' || c == '0' );
}
const std::vector<wxString>& GetDirectives() { return m_directives; }
protected:
void ReadDirectives();
private:
void readLibraryField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
void readNameField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
void readEnabledField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
bool readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
std::set<wxString>& aRefNames );
void readPins( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem, int& notConnectedCounter );
void writeIncludes( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions );
void writeModels( OUTPUTFORMATTER& aFormatter );
void writeItems( OUTPUTFORMATTER& aFormatter );
void writeDirectives( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions );
wxString m_title; ///< Spice simulation title found in the schematic sheet
std::vector<wxString> m_directives; ///< Spice directives found in the schematic sheet
std::map<wxString, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries
std::set<wxString> m_nets;
std::list<SPICE_ITEM> m_items; ///< Items representing schematic symbols in Spice world
};
#endif // NETLIST_EXPORTER_PSPICE_H

View File

@ -37,7 +37,7 @@
#include <netlist_exporter_base.h>
#include <netlist_exporter_orcadpcb2.h>
#include <netlist_exporter_cadstar.h>
#include <netlist_exporter_pspice.h>
#include <netlist_exporter_spice.h>
#include <netlist_exporter_kicad.h>
#include <netlist_exporter_xml.h>
@ -59,7 +59,7 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
wxString fileName = aFullFileName;
NETLIST_EXPORTER_BASE *helper;
NETLIST_EXPORTER_BASE *helper = nullptr;
SCHEMATIC* sch = &Schematic();
@ -78,7 +78,7 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
break;
case NET_TYPE_SPICE:
helper = new NETLIST_EXPORTER_PSPICE( sch );
helper = new NETLIST_EXPORTER_SPICE( sch );
break;
case NET_TYPE_BOM:

View File

@ -53,6 +53,8 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin
m_DashedLineDashRatio( 12.0 ),
m_DashedLineGapRatio( 3.0 ),
m_SpiceAdjustPassiveValues( false ),
m_SpiceSaveAllVoltages( false ),
m_SpiceSaveAllCurrents( false ),
m_NgspiceSimulatorSettings( nullptr )
{
EESCHEMA_SETTINGS* appSettings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
@ -195,6 +197,12 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin
m_params.emplace_back( new PARAM<bool>( "spice_adjust_passive_values",
&m_SpiceAdjustPassiveValues, false ) );
m_params.emplace_back( new PARAM<bool>( "spice_save_all_voltages",
&m_SpiceSaveAllVoltages, false ) );
m_params.emplace_back( new PARAM<bool>( "spice_save_all_currents",
&m_SpiceSaveAllCurrents, false ) );
m_params.emplace_back( new PARAM<wxString>( "spice_external_command",
&m_SpiceCommandString, "spice \"%I\"" ) );

View File

@ -70,6 +70,8 @@ public:
///< @todo These should probably be moved to the "schematic.simulator" path.
bool m_SpiceAdjustPassiveValues;
bool m_SpiceSaveAllVoltages;
bool m_SpiceSaveAllCurrents;
wxString m_SpiceCommandString; // A command string to run external spice
TEMPLATES m_TemplateFieldNames;

View File

@ -29,48 +29,7 @@
#include <macros.h> // for TO_UTF8 def
#include <wx/regex.h>
#include <wx/tokenzr.h>
wxString NGSPICE_CIRCUIT_MODEL::ComponentToVector(
const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam ) const
{
wxString res;
// Some of the flags should exclude mutually
wxASSERT( ( ( aType & SPT_VOLTAGE ) == 0 ) != ( ( aType & SPT_CURRENT ) == 0 ) );
wxASSERT( ( ( aType & SPT_AC_PHASE ) == 0 ) || ( ( aType & SPT_AC_MAG ) == 0 ) );
if( aType & SPT_VOLTAGE )
{
// netnames are escaped (can contain "{slash}" for '/') Unscape them:
wxString spicenet = UnescapeString( aName );
// Spice netlist netnames does not accept some chars, which are replaced
// by eeschema netlist generator.
// Replace these forbidden chars to find the actual spice net name
NETLIST_EXPORTER_PSPICE::ReplaceForbiddenChars( spicenet );
return wxString::Format( "V(%s)", spicenet );
}
else if( aType & SPT_CURRENT )
{
wxString device = GetSpiceDevice( aName ).Lower();
wxString param = aParam.Lower();
if( device.length() > 0 && device[0] == 'x' )
{
return "current probe of .subckt not yet implemented";
}
else
{
return wxString::Format( "@%s[%s]",
device,
param.IsEmpty() ? "i" : param );
}
}
return res;
}
#include <locale_io.h>
SIM_PLOT_TYPE NGSPICE_CIRCUIT_MODEL::VectorToSignal(
@ -108,47 +67,16 @@ SIM_PLOT_TYPE NGSPICE_CIRCUIT_MODEL::VectorToSignal(
}
const std::vector<wxString>& NGSPICE_CIRCUIT_MODEL::GetCurrents( SPICE_PRIMITIVE aPrimitive )
{
static const std::vector<wxString> passive = { "I" };
static const std::vector<wxString> diode = { "Id" };
static const std::vector<wxString> bjt = { "Ib", "Ic", "Ie" };
static const std::vector<wxString> mos = { "Ig", "Id", "Is" };
static const std::vector<wxString> empty;
switch( aPrimitive )
{
case SP_RESISTOR:
case SP_CAPACITOR:
case SP_INDUCTOR:
case SP_VSOURCE:
return passive;
case SP_DIODE:
return diode;
case SP_BJT:
return bjt;
case SP_MOSFET:
return mos;
default:
return empty;
}
}
wxString NGSPICE_CIRCUIT_MODEL::GetSheetSimCommand()
{
wxString simCmd;
UpdateDirectives( NET_ALL_FLAGS );
ReadDirectives();
for( const auto& dir : GetDirectives() )
for( const auto& directive : GetDirectives() )
{
if( IsSimCommand( dir ) )
simCmd += wxString::Format( "%s\r\n", dir );
if( IsSimCommand( directive ) )
simCmd += wxString::Format( "%s\r\n", directive );
}
return simCmd;
@ -223,55 +151,3 @@ bool NGSPICE_CIRCUIT_MODEL::ParseDCCommand( const wxString& aCmd, SPICE_DC_PARAM
return true;
}
void NGSPICE_CIRCUIT_MODEL::writeDirectives( OUTPUTFORMATTER* aFormatter, unsigned aCtl ) const
{
// Add a directive to obtain currents
//aFormatter->Print( 0, ".options savecurrents\n" ); // does not work :(
for( const auto& item : GetSpiceItems() )
{
for( const auto& current :
NGSPICE_CIRCUIT_MODEL::GetCurrents( (SPICE_PRIMITIVE) item.m_primitive ) )
{
if( !item.m_enabled )
continue;
/// @todo is it required to switch to lowercase
aFormatter->Print( 0, ".save %s\n",
TO_UTF8( ComponentToVector( item.m_refName, SPT_CURRENT, current ) ) );
}
}
// If we print out .save directives for currents, then it needs to be done for voltages as well
for( const auto& netMap : GetNetIndexMap() )
{
// the "0" and the "GND" nets are automatically saved internally by ngspice.
// Skip them
wxString netname = ComponentToVector( netMap.first, SPT_VOLTAGE );
if( netname == "V(0)" || netname == "V(GND)" )
continue;
aFormatter->Print( 0, ".save %s\n", TO_UTF8( netname ) );
}
if( m_simCommand.IsEmpty() )
{
// Fallback to the default behavior and just write all directives
NETLIST_EXPORTER_PSPICE::writeDirectives( aFormatter, aCtl );
}
else
{
// Dump all directives but simulation commands
for( const auto& dir : GetDirectives() )
{
if( !IsSimCommand( dir ) )
aFormatter->Print( 0, "%s\n", TO_UTF8( dir ) );
}
// Finish with our custom simulation command
aFormatter->Print( 0, "%s\n", TO_UTF8( m_simCommand ) );
}
}

View File

@ -27,7 +27,7 @@
#ifndef NETLIST_EXPORTER_PSPICE_SIM_H
#define NETLIST_EXPORTER_PSPICE_SIM_H
#include <netlist_exporters/netlist_exporter_pspice.h>
#include <netlist_exporters/netlist_exporter_spice.h>
#include <vector>
#include "sim_types.h"
@ -44,29 +44,15 @@ struct SPICE_DC_PARAMS
};
/// Special netlist exporter flavor that allows one to override simulation commands
class NGSPICE_CIRCUIT_MODEL : public NETLIST_EXPORTER_PSPICE, public SIMULATION_MODEL
class NGSPICE_CIRCUIT_MODEL : public NETLIST_EXPORTER_SPICE, public SIMULATION_MODEL
{
public:
NGSPICE_CIRCUIT_MODEL( SCHEMATIC_IFACE* aSchematic ) :
NETLIST_EXPORTER_PSPICE( aSchematic ),
m_options( 0 )
NETLIST_EXPORTER_SPICE( aSchematic )
{
}
virtual ~NGSPICE_CIRCUIT_MODEL() {}
/**
* Return name of Spice dataset for a specific plot.
*
* @param aName is name of the measured net or device
* @param aType describes the type of expected plot
* @param aParam is an optional parameter for devices, if absent it will return current (only
* for passive devices).
* @return Empty string if query is invalid, otherwise a plot name that
* can be requested from the simulator.
*/
wxString ComponentToVector( const wxString& aName, SIM_PLOT_TYPE aType,
const wxString& aParam = wxEmptyString ) const;
/**
* Return name of Spice dataset for a specific plot.
*
@ -77,11 +63,6 @@ public:
*/
SIM_PLOT_TYPE VectorToSignal( const std::string& aVector, wxString& aSignal ) const;
/**
* Return a list of currents that can be probed in a Spice primitive.
*/
static const std::vector<wxString>& GetCurrents( SPICE_PRIMITIVE aPrimitive );
void SetOptions( int aOptions )
{
m_options = aOptions;
@ -89,7 +70,7 @@ public:
bool GetNetlist( OUTPUTFORMATTER* aFormatter )
{
return NGSPICE_CIRCUIT_MODEL::Format( aFormatter, m_options );
return NGSPICE_CIRCUIT_MODEL::GenerateNetlist( *aFormatter, m_options );
}
/**
@ -157,11 +138,7 @@ public:
*/
static SIM_TYPE CommandToSimType( const wxString& aCmd );
protected:
void writeDirectives( OUTPUTFORMATTER* aFormatter, unsigned aCtl ) const override;
private:
///< Custom simulation command (has priority over the schematic sheet simulation commands)
wxString m_simCommand;
int m_options;

File diff suppressed because it is too large Load Diff

View File

@ -23,16 +23,42 @@
*/
#include <sim/sim_library.h>
#include <sim/sim_library_spice.h>
bool SIM_LIBRARY::ReadFile( const wxString& aFilename )
std::unique_ptr<SIM_LIBRARY> SIM_LIBRARY::Create( wxString aFilePath )
{
m_filename = aFilename;
std::unique_ptr<SIM_LIBRARY> library = std::make_unique<SIM_LIBRARY_SPICE>();
if( !library->ReadFile( aFilePath ) )
return nullptr;
return library;
}
bool SIM_LIBRARY::ReadFile( const wxString& aFilePath )
{
m_filePath = aFilePath;
return true;
}
std::vector<std::reference_wrapper<SIM_MODEL>> SIM_LIBRARY::GetModels()
SIM_MODEL* SIM_LIBRARY::FindModel( const wxString& aModelName ) const
{
for( unsigned i = 0; i < GetModelNames().size(); ++i )
{
wxString curModelName = GetModelNames().at( i );
if( curModelName == aModelName )
return m_models.at( i ).get();
}
return nullptr;
}
std::vector<std::reference_wrapper<SIM_MODEL>> SIM_LIBRARY::GetModels() const
{
std::vector<std::reference_wrapper<SIM_MODEL>> ret;

View File

@ -31,23 +31,30 @@
class SIM_LIBRARY
{
public:
static constexpr auto LIBRARY_FIELD = "Model_Library";
static constexpr auto NAME_FIELD = "Model_Name";
virtual ~SIM_LIBRARY() = default;
SIM_LIBRARY() = default;
virtual bool ReadFile( const wxString& aFilename ) = 0;
virtual void WriteFile( const wxString& aFilename ) = 0;
static std::unique_ptr<SIM_LIBRARY> Create( wxString aFilePath );
std::vector<std::reference_wrapper<SIM_MODEL>> GetModels();
const std::vector<wxString>& GetModelNames() { return m_modelNames; }
virtual bool ReadFile( const wxString& aFilePath ) = 0;
virtual void WriteFile( const wxString& aFilePath ) = 0;
wxString GetFilename() const { return m_filename; }
SIM_MODEL* FindModel( const wxString& aModelName ) const;
std::vector<std::reference_wrapper<SIM_MODEL>> GetModels() const;
const std::vector<wxString>& GetModelNames() const { return m_modelNames; }
wxString GetFilePath() const { return m_filePath; }
wxString GetErrorMessage() const { return m_errorMessage; }
protected:
std::vector<std::unique_ptr<SIM_MODEL>> m_models;
std::vector<wxString> m_modelNames;
wxString m_filename;
wxString m_filePath;
wxString m_errorMessage;
};

View File

@ -33,11 +33,8 @@ namespace SIM_LIBRARY_SPICE_PARSER
{
using namespace SPICE_GRAMMAR;
struct unknownLine : until<newline> {};
struct library : star<sor<spiceUnit,
unknownLine>> {};
// TODO: unknownLine is already handled in spiceUnit.
struct library : spiceSource {};
struct libraryGrammar : must<library, eof> {};
@ -51,61 +48,67 @@ namespace SIM_LIBRARY_SPICE_PARSER
};
bool SIM_LIBRARY_SPICE::ReadFile( const wxString& aFilename )
bool SIM_LIBRARY_SPICE::ReadFile( const wxString& aFilePath )
{
if( !SIM_LIBRARY::ReadFile( aFilename ) )
return false;
LOCALE_IO toggle;
tao::pegtl::file_input in( aFilename.ToStdString() );
std::unique_ptr<tao::pegtl::parse_tree::node> root;
if( !SIM_LIBRARY::ReadFile( aFilePath ) )
return false;
m_models.clear();
m_modelNames.clear();
try
{
root = tao::pegtl::parse_tree::parse<SIM_LIBRARY_SPICE_PARSER::libraryGrammar,
SIM_LIBRARY_SPICE_PARSER::librarySelector>
tao::pegtl::file_input in( aFilePath.ToStdString() );
auto root = tao::pegtl::parse_tree::parse<SIM_LIBRARY_SPICE_PARSER::libraryGrammar,
SIM_LIBRARY_SPICE_PARSER::librarySelector>
( in );
wxASSERT( root );
for( const auto& node : root->children )
{
if( node->is_type<SIM_LIBRARY_SPICE_PARSER::modelUnit>() )
{
m_models.push_back( SIM_MODEL::Create( node->string() ) );
if( node->children.size() != 1 )
{
m_errorMessage = wxString::Format(
"Captured %d name tokens, expected one", node->children.size() );
return false;
}
m_modelNames.emplace_back( node->children.at( 0 )->string() );
}
else if( node->is_type<SIM_LIBRARY_SPICE_PARSER::unknownLine>() )
{
// Do nothing.
}
else
{
m_errorMessage = wxString::Format( "Unhandled parse tree node: '%s'", node->string() );
return false;
}
}
return true;
}
catch( tao::pegtl::parse_error& e )
catch( const std::filesystem::filesystem_error& e )
{
m_errorMessage = wxString::Format( "Parsing failed: %s", e.what() );
return false;
}
wxASSERT( root );
for( const auto& node : root->children )
catch( const tao::pegtl::parse_error& e )
{
if( node->is_type<SIM_LIBRARY_SPICE_PARSER::modelUnit>() )
{
m_models.push_back( SIM_MODEL::Create( node->string() ) );
if( node->children.size() != 1 )
{
m_errorMessage = wxString::Format(
"Captured %d name tokens, expected one", node->children.size() );
return false;
}
m_modelNames.emplace_back( node->children.at( 0 )->string() );
}
else if( node->is_type<SIM_LIBRARY_SPICE_PARSER::unknownLine>() )
{
// Do nothing.
}
else
{
m_errorMessage = wxString::Format( "Unhandled parse tree node: '%s'", node->string() );
return false;
}
m_errorMessage = wxString::Format( "Parsing failed: %s", e.what() );
return false;
}
return true;
}
void SIM_LIBRARY_SPICE::WriteFile( const wxString& aFileName )
void SIM_LIBRARY_SPICE::WriteFile( const wxString& aFilePath )
{
}

View File

@ -33,8 +33,8 @@ class SIM_LIBRARY_SPICE : public SIM_LIBRARY
// We'll make SIM_LIBRARY have no subclasses probably.
public:
bool ReadFile( const wxString& aFilename ) override;
void WriteFile( const wxString& aFilename ) override;
bool ReadFile( const wxString& aFilePath ) override;
void WriteFile( const wxString& aFilePath ) override;
};
#endif // SIM_LIBRARY_SPICE_H

File diff suppressed because it is too large Load Diff

View File

@ -62,6 +62,9 @@ namespace SIM_MODEL_GRAMMAR
class SIM_MODEL
{
public:
static constexpr auto REFERENCE_FIELD = "Reference";
static constexpr auto VALUE_FIELD = "Value";
static constexpr auto DEVICE_TYPE_FIELD = "Model_Device";
static constexpr auto TYPE_FIELD = "Model_Type";
static constexpr auto PINS_FIELD = "Model_Pins";
@ -71,30 +74,31 @@ public:
DEFINE_ENUM_CLASS_WITH_ITERATOR( DEVICE_TYPE,
NONE,
RESISTOR,
CAPACITOR,
INDUCTOR,
R,
C,
L,
TLINE,
SWITCH,
SW,
DIODE,
D,
NPN,
PNP,
NJF,
PJF,
NJFET,
PJFET,
NMES,
PMES,
NMOS,
PMOS,
VSOURCE,
ISOURCE,
V,
I,
SUBCIRCUIT,
CODEMODEL,
RAWSPICE
SUBCKT,
XSPICE,
SPICE
)
struct DEVICE_INFO
@ -107,44 +111,44 @@ public:
DEFINE_ENUM_CLASS_WITH_ITERATOR( TYPE,
NONE,
RESISTOR_IDEAL,
RESISTOR_ADVANCED,
RESISTOR_BEHAVIORAL,
R,
R_ADV,
R_BEHAVIORAL,
CAPACITOR_IDEAL,
CAPACITOR_ADVANCED,
CAPACITOR_BEHAVIORAL,
C,
C_ADV,
C_BEHAVIORAL,
INDUCTOR_IDEAL,
INDUCTOR_ADVANCED,
INDUCTOR_BEHAVIORAL,
L,
L_ADV,
L_BEHAVIORAL,
TLINE_LOSSY,
TLINE_LOSSLESS,
TLINE_UNIFORM_RC,
TLINE_URC,
TLINE_KSPICE,
SWITCH_VCTRL,
SWITCH_ICTRL,
SW_V,
SW_I,
DIODE,
D,
NPN_GUMMEL_POON,
PNP_GUMMEL_POON,
NPN_GUMMELPOON,
PNP_GUMMELPOON,
NPN_VBIC,
PNP_VBIC,
//NPN_MEXTRAM,
//PNP_MEXTRAM,
NPN_HICUM_L2,
PNP_HICUM_L2,
NPN_HICUML2,
PNP_HICUML2,
//NPN_HICUM_L0,
//PNP_HICUM_L0,
NJF_SHICHMAN_HODGES,
PJF_SHICHMAN_HODGES,
NJFET_SHICHMANHODGES,
PJFET_SHICHMANHODGES,
NJF_PARKER_SKELLERN,
PJF_PARKER_SKELLERN,
NJFET_PARKERSKELLERN,
PJFET_PARKERSKELLERN,
NMES_STATZ,
@ -211,47 +215,49 @@ public:
NMOS_HISIM2,
PMOS_HISIM2,
NMOS_HISIM_HV1,
PMOS_HISIM_HV1,
NMOS_HISIMHV1,
PMOS_HISIMHV1,
NMOS_HISIM_HV2,
PMOS_HISIM_HV2,
NMOS_HISIMHV2,
PMOS_HISIMHV2,
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,
V_DC,
V_SIN,
V_PULSE,
V_EXP,
V_SFAM,
V_SFFM,
V_PWL,
V_WHITENOISE,
V_PINKNOISE,
V_BURSTNOISE,
V_RANDUNIFORM,
V_RANDNORMAL,
V_RANDEXP,
V_RANDPOISSON,
V_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,
I_DC,
I_SIN,
I_PULSE,
I_EXP,
I_SFAM,
I_SFFM,
I_PWL,
I_WHITENOISE,
I_PINKNOISE,
I_BURSTNOISE,
I_RANDUNIFORM,
I_RANDNORMAL,
I_RANDEXP,
I_RANDPOISSON,
I_BEHAVIORAL,
SUBCIRCUIT,
CODEMODEL,
RAWSPICE
SUBCKT,
XSPICE,
SPICE
)
struct INFO
@ -264,8 +270,8 @@ public:
struct SPICE_INFO
{
wxString itemType;
wxString typeString = "";
wxString primitive;
wxString modelType = "";
wxString inlineTypeString = "";
int level = 0;
bool hasExpression = false;
@ -277,8 +283,8 @@ public:
{
static constexpr auto NOT_CONNECTED = 0;
int symbolPinNumber;
const wxString name;
int symbolPinNumber;
};
@ -314,21 +320,22 @@ public:
wxString name;
unsigned int id = 0; // Legacy.
DIR dir = DIR::INOUT;
SIM_VALUE_BASE::TYPE type;
SIM_VALUE::TYPE type = SIM_VALUE::TYPE::FLOAT;
FLAGS flags = {}; // Legacy
wxString unit = "";
CATEGORY category = CATEGORY::PRINCIPAL;
wxString defaultValue = "";
wxString defaultValueOfOtherVariant = ""; // Legacy.
wxString description = "";
bool isInstanceParam = false;
};
std::unique_ptr<SIM_VALUE_BASE> value;
std::unique_ptr<SIM_VALUE> value;
const INFO& info;
bool isOtherVariant = false; // Legacy.
PARAM( const INFO& aInfo, bool aIsOtherVariant = false )
: value( SIM_VALUE_BASE::Create( aInfo.type ) ),
: value( SIM_VALUE::Create( aInfo.type ) ),
info( aInfo ),
isOtherVariant( aIsOtherVariant )
{}
@ -348,7 +355,10 @@ public:
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, int aSymbolPinCount = 0 );
static std::unique_ptr<SIM_MODEL> Create( const std::string& aSpiceCode );
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel );
template <typename T>
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel, int aSymbolPinCount,
const std::vector<T>& aFields );
template <typename T>
static std::unique_ptr<SIM_MODEL> Create( int aSymbolPinCount, const std::vector<T>& aFields );
@ -388,25 +398,34 @@ public:
virtual void WriteDataLibFields( std::vector<LIB_FIELD>& aFields );
virtual wxString GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const;
virtual bool HasToIncludeSpiceLibrary() const { return GetBaseModel() && !HasOverrides(); }
virtual wxString GenerateSpiceModelLine( const wxString& aModelName ) const;
virtual SPICE_INFO GetSpiceInfo() const;
virtual wxString GenerateSpiceItemName( const wxString& aRefName ) const;
wxString GenerateSpiceItemLine( const wxString& aRefName, const wxString& aModelName ) const;
virtual wxString GenerateSpiceItemLine( const wxString& aRefName,
const wxString& aModelName,
const std::vector<wxString>& aPinNetNames ) const;
virtual wxString GenerateSpiceTuningLine( const wxString& aSymbol ) const;
virtual wxString GenerateSpicePreview( const wxString& aModelName ) const;
SPICE_INFO GetSpiceInfo() const;
virtual std::vector<wxString> GenerateSpiceCurrentNames( const wxString& aRefName ) const;
bool ParsePinsField( int aSymbolPinCount, const wxString& aPinsField );
void AddPin( const PIN& aPin );
int FindModelPinNumber( int aSymbolPinNumber );
void AddParam( const PARAM::INFO& aInfo, bool aIsOtherVariant = false );
DEVICE_TYPE GetDeviceType() const { return TypeInfo( GetType() ).deviceType; }
TYPE GetType() const { return m_type; }
const SIM_MODEL* GetBaseModel() const { return m_baseModel; }
void SetBaseModel( const SIM_MODEL& aBaseModel ) { m_baseModel = &aBaseModel; }
virtual void SetBaseModel( const SIM_MODEL& aBaseModel ) { m_baseModel = &aBaseModel; }
int GetPinCount() const { return static_cast<int>( m_pins.size() ); }
const PIN& GetPin( int aIndex ) const { return m_pins.at( aIndex ); }
@ -421,7 +440,9 @@ public:
const PARAM& GetParam( int aParamIndex ) const; // Return base parameter unless it's overridden.
const PARAM& GetUnderlyingParam( int aParamIndex ) const; // Return the actual parameter.
const PARAM& GetBaseParam( int aParamIndex ) const; // Always return base parameter if it exists.
virtual bool SetParamValue( int aParamIndex, const wxString& aValue );
virtual bool SetParamValue( int aParamIndex, const wxString& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation
= SIM_VALUE_GRAMMAR::NOTATION::SI );
bool HasOverrides() const;
bool HasNonPrincipalOverrides() const;
@ -432,17 +453,12 @@ public:
protected:
SIM_MODEL( TYPE aType );
wxString m_spiceCode;
private:
static std::unique_ptr<SIM_MODEL> create( TYPE aType );
static TYPE readTypeFromSpiceTypeString( const std::string& aTypeString );
wxString m_spiceCode;
const SIM_MODEL* m_baseModel;
const TYPE m_type;
std::vector<PIN> m_pins;
std::vector<PARAM> m_params;
template <typename T>
void doReadDataFields( int aSymbolPinCount, const std::vector<T>* aFields );
@ -457,13 +473,22 @@ private:
wxString generateTypeField() const;
wxString generatePinsField() const;
void parsePinsField( int aSymbolPinCount, const wxString& aPinsField );
wxString generateParamsField( const wxString& aPairSeparator ) const;
void parseParamsField( const wxString& aParamsField );
bool parseParamsField( const wxString& aParamsField );
virtual bool setParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue );
// TODO: Rename.
virtual bool setParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation
= SIM_VALUE_GRAMMAR::NOTATION::SPICE );
const SIM_MODEL* m_baseModel;
const TYPE m_type;
std::vector<PIN> m_pins;
std::vector<PARAM> m_params;
};
#endif // SIM_MODEL_H

View File

@ -37,23 +37,17 @@ SIM_MODEL_BEHAVIORAL::SIM_MODEL_BEHAVIORAL( TYPE aType )
switch( aType )
{
case TYPE::RESISTOR_BEHAVIORAL: AddParam( resistor ); break;
case TYPE::CAPACITOR_BEHAVIORAL: AddParam( capacitor ); break;
case TYPE::INDUCTOR_BEHAVIORAL: AddParam( inductor ); break;
case TYPE::VSOURCE_BEHAVIORAL: AddParam( vsource ); break;
case TYPE::ISOURCE_BEHAVIORAL: AddParam( isource ); break;
case TYPE::R_BEHAVIORAL: AddParam( resistor ); break;
case TYPE::C_BEHAVIORAL: AddParam( capacitor ); break;
case TYPE::L_BEHAVIORAL: AddParam( inductor ); break;
case TYPE::V_BEHAVIORAL: AddParam( vsource ); break;
case TYPE::I_BEHAVIORAL: AddParam( isource ); break;
default:
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_IDEAL" );
}
}
wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const
{
return "";
}
wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceModelLine( const wxString& aModelName ) const
{
return "";
@ -68,18 +62,18 @@ wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceItemLine( const wxString& aRefName,
switch( GetType() )
{
case TYPE::RESISTOR_BEHAVIORAL:
case TYPE::CAPACITOR_BEHAVIORAL:
case TYPE::INDUCTOR_BEHAVIORAL:
case TYPE::R_BEHAVIORAL:
case TYPE::C_BEHAVIORAL:
case TYPE::L_BEHAVIORAL:
return SIM_MODEL::GenerateSpiceItemLine( aRefName,
GetParam( 0 ).value->ToString(),
aPinNetNames );
case TYPE::VSOURCE_BEHAVIORAL:
case TYPE::V_BEHAVIORAL:
return SIM_MODEL::GenerateSpiceItemLine( aRefName,
wxString::Format( "V=%s", GetParam( 0 ).value->ToString() ), aPinNetNames );
case TYPE::ISOURCE_BEHAVIORAL:
case TYPE::I_BEHAVIORAL:
return SIM_MODEL::GenerateSpiceItemLine( aRefName,
wxString::Format( "I=%s", GetParam( 0 ).value->ToString() ), aPinNetNames );
@ -90,19 +84,13 @@ wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceItemLine( const wxString& aRefName,
}
std::vector<wxString> SIM_MODEL_BEHAVIORAL::getPinNames() const
{
return { "+", "-" };
}
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.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = unit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.description = description;

View File

@ -33,14 +33,14 @@ class SIM_MODEL_BEHAVIORAL : public SIM_MODEL
public:
SIM_MODEL_BEHAVIORAL( TYPE aType );
wxString GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const override;
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
wxString GenerateSpiceItemLine( const wxString& aRefName,
const wxString& aModelName,
const std::vector<wxString>& aPinNetNames ) const override;
private:
std::vector<wxString> getPinNames() const override;
std::vector<wxString> getPinNames() const override { return { "+", "-" }; }
static PARAM::INFO makeParamInfo( wxString name, wxString description, wxString unit );
};

View File

@ -36,18 +36,40 @@ SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType )
switch( aType )
{
case TYPE::RESISTOR_IDEAL: AddParam( resistor ); break;
case TYPE::CAPACITOR_IDEAL: AddParam( capacitor ); break;
case TYPE::INDUCTOR_IDEAL: AddParam( inductor ); break;
case TYPE::R: AddParam( resistor ); break;
case TYPE::C: AddParam( capacitor ); break;
case TYPE::L: AddParam( inductor ); break;
default:
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_IDEAL" );
}
}
wxString SIM_MODEL_IDEAL::GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const
void SIM_MODEL_IDEAL::ReadDataSchFields( int aSymbolPinCount,
const std::vector<SCH_FIELD>* aFields )
{
return "";
if( !GetFieldValue( aFields, PARAMS_FIELD ).IsEmpty() )
SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields );
else
{
// Inferred model.
ParsePinsField( aSymbolPinCount, PINS_FIELD );
SetParamValue( 0, GetFieldValue( aFields, VALUE_FIELD ) );
}
}
void SIM_MODEL_IDEAL::ReadDataLibFields( int aSymbolPinCount,
const std::vector<LIB_FIELD>* aFields )
{
if( !GetFieldValue( aFields, PARAMS_FIELD ).IsEmpty() )
SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields );
else
{
// Inferred model.
ParsePinsField( aSymbolPinCount, PINS_FIELD );
SetParamValue( 0, GetFieldValue( aFields, VALUE_FIELD ) );
}
}
@ -66,18 +88,12 @@ wxString SIM_MODEL_IDEAL::GenerateSpiceItemLine( const wxString& aRefName,
}
std::vector<wxString> SIM_MODEL_IDEAL::getPinNames() const
{
return { "+", "-" };
}
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.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.description = aDescription;

View File

@ -33,14 +33,17 @@ class SIM_MODEL_IDEAL : public SIM_MODEL
public:
SIM_MODEL_IDEAL( TYPE aType );
wxString GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const override;
void ReadDataSchFields( int aSymbolPinCount, const std::vector<SCH_FIELD>* aFields ) override;
void ReadDataLibFields( int aSymbolPinCount, const std::vector<LIB_FIELD>* aFields ) override;
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
wxString GenerateSpiceItemLine( const wxString& aRefName,
const wxString& aModelName,
const std::vector<wxString>& aPinNetNames ) const override;
private:
std::vector<wxString> getPinNames() const override;
std::vector<wxString> getPinNames() const override { return { "+", "-" }; }
static PARAM::INFO makeParamInfo( wxString aName, wxString aDescription, wxString aUnit );
};

View File

@ -23,6 +23,7 @@
*/
#include <sim/sim_model_ngspice.h>
#include <locale_io.h>
using TYPE = SIM_MODEL::TYPE;
@ -40,6 +41,41 @@ SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType )
}
std::vector<wxString> SIM_MODEL_NGSPICE::GenerateSpiceCurrentNames( const wxString& aRefName ) const
{
LOCALE_IO toggle;
switch( TypeInfo( GetType() ).deviceType )
{
case DEVICE_TYPE::NPN:
case DEVICE_TYPE::PNP:
return { wxString::Format( "I(%s:c)", aRefName ),
wxString::Format( "I(%s:b)", aRefName ),
wxString::Format( "I(%s:e)", aRefName ) };
case DEVICE_TYPE::NJFET:
case DEVICE_TYPE::PJFET:
case DEVICE_TYPE::NMES:
case DEVICE_TYPE::PMES:
case DEVICE_TYPE::NMOS:
case DEVICE_TYPE::PMOS:
return { wxString::Format( "I(%s:d)", aRefName ),
wxString::Format( "I(%s:g)", aRefName ),
wxString::Format( "I(%s:s)", aRefName ) };
case DEVICE_TYPE::R:
case DEVICE_TYPE::C:
case DEVICE_TYPE::L:
case DEVICE_TYPE::D:
return SIM_MODEL::GenerateSpiceCurrentNames( aRefName );
default:
wxFAIL_MSG( "Unhandled model device type" );
return {};
}
}
std::vector<wxString> SIM_MODEL_NGSPICE::getPinNames() const
{
return NGSPICE::ModelInfo( getModelType() ).pinNames;
@ -51,28 +87,28 @@ NGSPICE::MODEL_TYPE SIM_MODEL_NGSPICE::getModelType() const
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::R_ADV: return NGSPICE::MODEL_TYPE::RESISTOR;
case TYPE::C_ADV: return NGSPICE::MODEL_TYPE::CAPACITOR;
case TYPE::L_ADV: 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_URC: 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::SW_V: return NGSPICE::MODEL_TYPE::SWITCH;
case TYPE::SW_I: return NGSPICE::MODEL_TYPE::CSWITCH;
case TYPE::D: return NGSPICE::MODEL_TYPE::DIODE;
case TYPE::NPN_GUMMEL_POON:
case TYPE::PNP_GUMMEL_POON: return NGSPICE::MODEL_TYPE::BJT;
case TYPE::NPN_GUMMELPOON:
case TYPE::PNP_GUMMELPOON: 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::NPN_HICUML2:
case TYPE::PNP_HICUML2: 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::NJFET_SHICHMANHODGES:
case TYPE::PJFET_SHICHMANHODGES: return NGSPICE::MODEL_TYPE::JFET;
case TYPE::NJFET_PARKERSKELLERN:
case TYPE::PJFET_PARKERSKELLERN: return NGSPICE::MODEL_TYPE::JFET2;
case TYPE::NMES_STATZ:
case TYPE::PMES_STATZ: return NGSPICE::MODEL_TYPE::MES;
@ -111,10 +147,10 @@ NGSPICE::MODEL_TYPE SIM_MODEL_NGSPICE::getModelType() const
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;
case TYPE::NMOS_HISIMHV1:
case TYPE::PMOS_HISIMHV1: return NGSPICE::MODEL_TYPE::HISIMHV1;
case TYPE::NMOS_HISIMHV2:
case TYPE::PMOS_HISIMHV2: return NGSPICE::MODEL_TYPE::HISIMHV2;
default:
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_NGSPICE" );
@ -127,11 +163,11 @@ bool SIM_MODEL_NGSPICE::getIsOtherVariant()
{
switch( GetType() )
{
case TYPE::PNP_GUMMEL_POON:
case TYPE::PNP_GUMMELPOON:
case TYPE::PNP_VBIC:
case TYPE::PNP_HICUM_L2:
case TYPE::PJF_SHICHMAN_HODGES:
case TYPE::PJF_PARKER_SKELLERN:
case TYPE::PNP_HICUML2:
case TYPE::PJFET_SHICHMANHODGES:
case TYPE::PJFET_PARKERSKELLERN:
case TYPE::PMES_STATZ:
case TYPE::PMES_YTTERDAL:
case TYPE::PMES_HFET1:
@ -150,8 +186,8 @@ bool SIM_MODEL_NGSPICE::getIsOtherVariant()
case TYPE::PMOS_B3SOIDD:
case TYPE::PMOS_B3SOIPD:
case TYPE::PMOS_HISIM2:
case TYPE::PMOS_HISIM_HV1:
case TYPE::PMOS_HISIM_HV2:
case TYPE::PMOS_HISIMHV1:
case TYPE::PMOS_HISIMHV2:
return true;
default:

View File

@ -34,6 +34,8 @@ class SIM_MODEL_NGSPICE : public SIM_MODEL
public:
SIM_MODEL_NGSPICE( TYPE aType );
std::vector<wxString> GenerateSpiceCurrentNames( const wxString& aRefName ) const override;
private:
std::vector<wxString> getPinNames() const override;

View File

@ -35,12 +35,6 @@ SIM_MODEL_SOURCE::SIM_MODEL_SOURCE( TYPE aType )
}
wxString SIM_MODEL_SOURCE::GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const
{
return "";
}
wxString SIM_MODEL_SOURCE::GenerateSpiceModelLine( const wxString& aModelName ) const
{
return "";
@ -64,12 +58,15 @@ wxString SIM_MODEL_SOURCE::GenerateSpiceItemLine( const wxString& aRefName,
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> vdc = makeDc( "v", "V" );
static std::vector<PARAM::INFO> idc = makeDc( "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> vpulse = makePulse( "v", "V" );
static std::vector<PARAM::INFO> ipulse = makePulse( "i", "A" );
static std::vector<PARAM::INFO> vexp = makeExp( "v", "V" );
static std::vector<PARAM::INFO> iexp = makeExp( "i", "A" );
@ -105,32 +102,34 @@ const std::vector<PARAM::INFO>& SIM_MODEL_SOURCE::makeParams( TYPE aType )
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;
case TYPE::V_DC: return vdc;
case TYPE::I_DC: return idc;
case TYPE::V_SIN: return vsin;
case TYPE::I_SIN: return isin;
case TYPE::V_PULSE: return vpulse;
case TYPE::I_PULSE: return ipulse;
case TYPE::V_EXP: return vexp;
case TYPE::I_EXP: return iexp;
case TYPE::V_SFAM: return vsfam;
case TYPE::I_SFAM: return isfam;
case TYPE::V_SFFM: return vsffm;
case TYPE::I_SFFM: return isffm;
case TYPE::V_PWL: return vpwl;
case TYPE::I_PWL: return ipwl;
case TYPE::V_WHITENOISE: return vwhitenoise;
case TYPE::I_WHITENOISE: return iwhitenoise;
case TYPE::V_PINKNOISE: return vpinknoise;
case TYPE::I_PINKNOISE: return ipinknoise;
case TYPE::V_BURSTNOISE: return vburstnoise;
case TYPE::I_BURSTNOISE: return iburstnoise;
case TYPE::V_RANDUNIFORM: return vrandomuniform;
case TYPE::I_RANDUNIFORM: return irandomuniform;
case TYPE::V_RANDNORMAL: return vrandomnormal;
case TYPE::I_RANDNORMAL: return irandomnormal;
case TYPE::V_RANDEXP: return vrandomexp;
case TYPE::I_RANDEXP: return irandomexp;
case TYPE::V_RANDPOISSON: return vrandompoisson;
case TYPE::I_RANDPOISSON: return irandompoisson;
default:
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_SOURCE" );
static std::vector<PARAM::INFO> empty;
@ -139,25 +138,26 @@ const std::vector<PARAM::INFO>& SIM_MODEL_SOURCE::makeParams( TYPE aType )
}
bool SIM_MODEL_SOURCE::SetParamValue( int aParamIndex, const wxString& aValue )
bool SIM_MODEL_SOURCE::SetParamValue( int aParamIndex, const wxString& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation )
{
// Sources are special. All preceding parameter values must be filled. If they are not, fill
// them out automatically. If a value is nulled, delete everything after it.
if( aValue.IsEmpty() )
{
for( int i = aParamIndex; i < GetParamCount(); ++i )
SIM_MODEL::SetParamValue( i, "" );
SIM_MODEL::SetParamValue( i, "", aNotation );
}
else
{
for( int i = 0; i < aParamIndex; ++i )
{
if( GetParam( i ).value->ToString().IsEmpty() )
SIM_MODEL::SetParamValue( i, "0" );
SIM_MODEL::SetParamValue( i, "0", aNotation );
}
}
return SIM_MODEL::SetParamValue( aParamIndex, aValue );
return SIM_MODEL::SetParamValue( aParamIndex, aValue, aNotation );
}
@ -167,73 +167,17 @@ std::vector<wxString> SIM_MODEL_SOURCE::getPinNames() const
}
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePulse( wxString aPrefix, wxString aUnit )
std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeDc( wxString aPrefix, wxString aUnit )
{
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
paramInfo.name = aPrefix + "1";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.name = "dc";
paramInfo.type = SIM_VALUE::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.category = SIM_MODEL::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";
paramInfo.description = "DC value";
paramInfos.push_back( paramInfo );
return paramInfos;
@ -245,24 +189,24 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSin( wxString aPrefix, wxString a
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
paramInfo.name = aPrefix + "o";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.name = "dc";
paramInfo.type = SIM_VALUE::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.name = "ampl";
paramInfo.type = SIM_VALUE::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.name = "f";
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "Hz";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "1/tstop";
@ -270,7 +214,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSin( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = "td";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -278,7 +222,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSin( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = "theta";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "1/s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -286,7 +230,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSin( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = "phase";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "deg";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -297,13 +241,86 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSin( wxString aPrefix, wxString a
}
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::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::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::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::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::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::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::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::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::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.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -311,7 +328,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeExp( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = aPrefix + "2";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -319,7 +336,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeExp( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = "td1";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -327,7 +344,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeExp( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = "tau1";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "tstep";
@ -335,7 +352,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeExp( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = "td2";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "td1+tstep";
@ -343,7 +360,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeExp( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = "tau2";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "tstep";
@ -359,15 +376,15 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSfam( wxString aPrefix, wxString
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
paramInfo.name = aPrefix + "o";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.name = "dc";
paramInfo.type = SIM_VALUE::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.name = "ampl";
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -375,7 +392,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSfam( wxString aPrefix, wxString
paramInfos.push_back( paramInfo );
paramInfo.name = "mo";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -383,7 +400,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSfam( wxString aPrefix, wxString
paramInfos.push_back( paramInfo );
paramInfo.name = "fc";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "Hz";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -391,7 +408,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSfam( wxString aPrefix, wxString
paramInfos.push_back( paramInfo );
paramInfo.name = "mf";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "Hz";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -407,16 +424,16 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSffm( wxString aPrefix, wxString
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
paramInfo.name = aPrefix + "o";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.name = "dc";
paramInfo.type = SIM_VALUE::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.name = "ampl";
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -424,7 +441,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSffm( wxString aPrefix, wxString
paramInfos.push_back( paramInfo );
paramInfo.name = "fc";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "Hz";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "1/tstop";
@ -432,7 +449,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSffm( wxString aPrefix, wxString
paramInfos.push_back( paramInfo );
paramInfo.name = "mdi";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -440,7 +457,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSffm( wxString aPrefix, wxString
paramInfos.push_back( paramInfo );
paramInfo.name = "fs";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "Hz";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "1/tstop";
@ -448,7 +465,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSffm( wxString aPrefix, wxString
paramInfos.push_back( paramInfo );
paramInfo.name = "phasec";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "deg";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -456,7 +473,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeSffm( wxString aPrefix, wxString
paramInfos.push_back( paramInfo );
paramInfo.name = "phases";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "deg";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -474,7 +491,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePwl( wxString aPrefix, wxString a
PARAM::INFO paramInfo;
paramInfo.name = "t";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT_VECTOR;
paramInfo.type = SIM_VALUE::TYPE::FLOAT_VECTOR;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -482,7 +499,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePwl( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = aPrefix;
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT_VECTOR;
paramInfo.type = SIM_VALUE::TYPE::FLOAT_VECTOR;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -490,7 +507,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePwl( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = "repeat";
paramInfo.type = SIM_VALUE_BASE::TYPE::BOOL;
paramInfo.type = SIM_VALUE::TYPE::BOOL;
paramInfo.unit = "";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -498,7 +515,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePwl( wxString aPrefix, wxString a
paramInfos.push_back( paramInfo );
paramInfo.name = "td";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -514,8 +531,8 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeWhiteNoise( wxString aPrefix, wxS
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
paramInfo.name = aPrefix + "o";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.name = "dc";
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -523,7 +540,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeWhiteNoise( wxString aPrefix, wxS
paramInfos.push_back( paramInfo );
paramInfo.name = "na";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -531,7 +548,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeWhiteNoise( wxString aPrefix, wxS
paramInfos.push_back( paramInfo );
paramInfo.name = "nt";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -547,8 +564,8 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePinkNoise( wxString aPrefix, wxSt
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
paramInfo.name = aPrefix + "o";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.name = "dc";
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "";
@ -556,7 +573,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePinkNoise( wxString aPrefix, wxSt
paramInfos.push_back( paramInfo );
paramInfo.name = "nalpha";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -564,7 +581,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePinkNoise( wxString aPrefix, wxSt
paramInfos.push_back( paramInfo );
paramInfo.name = "namp";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -572,7 +589,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makePinkNoise( wxString aPrefix, wxSt
paramInfos.push_back( paramInfo );
paramInfo.name = "nt";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -589,7 +606,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeBurstNoise( wxString aPrefix, wxS
PARAM::INFO paramInfo;
paramInfo.name = "rtsam";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -597,7 +614,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeBurstNoise( wxString aPrefix, wxS
paramInfos.push_back( paramInfo );
paramInfo.name = "rtscapt";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -605,7 +622,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeBurstNoise( wxString aPrefix, wxS
paramInfos.push_back( paramInfo );
paramInfo.name = "rtsemt";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -613,7 +630,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeBurstNoise( wxString aPrefix, wxS
paramInfos.push_back( paramInfo );
paramInfo.name = "nt";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -630,7 +647,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomUniform( wxString aPrefix,
PARAM::INFO paramInfo;
paramInfo.name = "min";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "-0.5";
@ -638,7 +655,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomUniform( wxString aPrefix,
paramInfos.push_back( paramInfo );
paramInfo.name = "max";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0.5";
@ -646,7 +663,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomUniform( wxString aPrefix,
paramInfos.push_back( paramInfo );
paramInfo.name = "td";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -663,7 +680,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomNormal( wxString aPrefix, w
PARAM::INFO paramInfo;
paramInfo.name = "mean";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -671,7 +688,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomNormal( wxString aPrefix, w
paramInfos.push_back( paramInfo );
paramInfo.name = "stddev";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "1";
@ -679,7 +696,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomNormal( wxString aPrefix, w
paramInfos.push_back( paramInfo );
paramInfo.name = "td";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -696,7 +713,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomExp( wxString aPrefix, wxSt
PARAM::INFO paramInfo;
paramInfo.name = "offset";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -704,7 +721,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomExp( wxString aPrefix, wxSt
paramInfos.push_back( paramInfo );
paramInfo.name = "mean";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "1";
@ -712,7 +729,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomExp( wxString aPrefix, wxSt
paramInfos.push_back( paramInfo );
paramInfo.name = "td";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -729,7 +746,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomPoisson( wxString aPrefix,
PARAM::INFO paramInfo;
paramInfo.name = "offset";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";
@ -737,7 +754,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomPoisson( wxString aPrefix,
paramInfos.push_back( paramInfo );
paramInfo.name = "lambda";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = aUnit;
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "1";
@ -745,7 +762,7 @@ std::vector<PARAM::INFO> SIM_MODEL_SOURCE::makeRandomPoisson( wxString aPrefix,
paramInfos.push_back( paramInfo );
paramInfo.name = "td";
paramInfo.type = SIM_VALUE_BASE::TYPE::FLOAT;
paramInfo.type = SIM_VALUE::TYPE::FLOAT;
paramInfo.unit = "s";
paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "0";

View File

@ -33,13 +33,13 @@ class SIM_MODEL_SOURCE : public SIM_MODEL
public:
SIM_MODEL_SOURCE( TYPE aType );
wxString GenerateSpiceIncludeLine( const wxString& aLibraryFilename ) const override;
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
wxString GenerateSpiceItemLine( const wxString& aRefName,
const wxString& aModelName,
const std::vector<wxString>& aPinNetNames ) const override;
bool SetParamValue( int aParamIndex, const wxString& aValue ) override;
bool SetParamValue( int aParamIndex, const wxString& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) override;
bool HasAutofill() const override { return true; }
@ -48,8 +48,9 @@ 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> makeDc( wxString aPrefix, wxString aUnit );
static std::vector<PARAM::INFO> makeSin( wxString aPrefix, wxString aUnit );
static std::vector<PARAM::INFO> makePulse( 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 );

View File

@ -22,7 +22,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <sim/sim_model_rawspice.h>
#include <sim/sim_model_spice.h>
#include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp>
@ -34,7 +34,8 @@ SIM_MODEL_RAWSPICE::SIM_MODEL_RAWSPICE( TYPE aType )
bool SIM_MODEL_RAWSPICE::setParamFromSpiceCode( const wxString& aParamName,
const wxString& aParamValue )
const wxString& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation )
{
int i = 0;
@ -51,7 +52,7 @@ bool SIM_MODEL_RAWSPICE::setParamFromSpiceCode( const wxString& aParamName,
std::unique_ptr<PARAM::INFO> paramInfo = std::make_unique<PARAM::INFO>();
paramInfo->name = aParamName.Lower();
paramInfo->type = SIM_VALUE_BASE::TYPE::STRING;
paramInfo->type = SIM_VALUE::TYPE::STRING;
m_paramInfos.push_back( std::move( paramInfo ) );
AddParam( *m_paramInfos.back() );
@ -59,9 +60,9 @@ bool SIM_MODEL_RAWSPICE::setParamFromSpiceCode( const wxString& aParamName,
try
{
GetParam( i ).value->FromString( wxString( aParamValue ) );
GetParam( i ).value->FromString( wxString( aParamValue ), aNotation );
}
catch( KI_PARAM_ERROR& e )
catch( const KI_PARAM_ERROR& e )
{
// Shouldn't happen since it's TYPE::STRING.
return false;

View File

@ -36,7 +36,9 @@ public:
//bool ReadSpiceCode( const std::string& aSpiceCode ) override;
private:
bool setParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue ) override;
bool setParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation
= SIM_VALUE_GRAMMAR::NOTATION::SPICE ) override;
std::vector<std::unique_ptr<PARAM::INFO>> m_paramInfos;
};

View File

@ -1,31 +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 <sim/sim_model_subcircuit.h>
SIM_MODEL_SUBCIRCUIT::SIM_MODEL_SUBCIRCUIT( TYPE aType )
: SIM_MODEL( aType )
{
}

View File

@ -0,0 +1,146 @@
/*
* 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_subckt.h>
#include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp>
namespace SIM_MODEL_SUBCKT_PARSER
{
using namespace SIM_MODEL_GRAMMAR;
template <typename Rule> struct spiceUnitSelector : std::false_type {};
template <> struct spiceUnitSelector<dotSubckt> : std::true_type {};
template <> struct spiceUnitSelector<modelName> : std::true_type {};
template <> struct spiceUnitSelector<dotSubcktPinName> : std::true_type {};
template <> struct spiceUnitSelector<param> : std::true_type {};
template <> struct spiceUnitSelector<number<SIM_VALUE::TYPE::INT, NOTATION::SPICE>>
: std::true_type {};
template <> struct spiceUnitSelector<number<SIM_VALUE::TYPE::FLOAT, NOTATION::SPICE>>
: std::true_type {};
}
SIM_MODEL_SUBCKT::SIM_MODEL_SUBCKT( TYPE aType )
: SIM_MODEL( aType )
{
}
bool SIM_MODEL_SUBCKT::ReadSpiceCode( const std::string& aSpiceCode )
{
tao::pegtl::string_input<> in( aSpiceCode, "from_content" );
std::unique_ptr<tao::pegtl::parse_tree::node> root;
try
{
root = tao::pegtl::parse_tree::parse<SIM_MODEL_SUBCKT_PARSER::spiceUnitGrammar,
SIM_MODEL_SUBCKT_PARSER::spiceUnitSelector>
( in );
}
catch( const tao::pegtl::parse_error& e )
{
return false;
}
wxASSERT( root );
for( const auto& node : root->children )
{
if( node->is_type<SIM_MODEL_SUBCKT_PARSER::dotSubckt>() )
{
for( const auto& subnode : node->children )
{
if( subnode->is_type<SIM_MODEL_SUBCKT_PARSER::modelName>() )
{
}
else if( subnode->is_type<SIM_MODEL_SUBCKT_PARSER::dotSubcktPinName>() )
{
AddPin( { subnode->string(), GetPinCount() + 1 } );
}
else if( subnode->is_type<SIM_MODEL_SUBCKT_PARSER::param>() )
{
m_paramInfos.push_back( std::make_unique<PARAM::INFO>() );
m_paramInfos.back()->name = subnode->string();
m_paramInfos.back()->isInstanceParam = true;
AddParam( *m_paramInfos.back() );
}
else if( subnode->is_type<
SIM_MODEL_SUBCKT_PARSER::number<SIM_VALUE::TYPE::INT,
SIM_MODEL_SUBCKT_PARSER::NOTATION::SPICE>>()
|| subnode->is_type<
SIM_MODEL_SUBCKT_PARSER::number<SIM_VALUE::TYPE::FLOAT,
SIM_MODEL_SUBCKT_PARSER::NOTATION::SPICE>>() )
{
wxASSERT( m_paramInfos.size() > 0 );
m_paramInfos.back()->defaultValue = subnode->string();
}
}
}
else
{
wxFAIL_MSG( "Unhandled parse tree node" );
return false;
}
}
m_spiceCode = aSpiceCode;
return true;
}
wxString SIM_MODEL_SUBCKT::GenerateSpiceModelLine( const wxString& aModelName ) const
{
return "";
}
std::vector<wxString> SIM_MODEL_SUBCKT::GenerateSpiceCurrentNames( const wxString& aRefName ) const
{
std::vector<wxString> currentNames;
for( int i = 0; i < GetPinCount(); ++i )
currentNames.push_back( wxString::Format( "I(%s:%s)",
GenerateSpiceItemName( aRefName ),
GetPin( i ).name ) );
return currentNames;
}
void SIM_MODEL_SUBCKT::SetBaseModel( const SIM_MODEL& aBaseModel )
{
SIM_MODEL::SetBaseModel( aBaseModel );
// Pins aren't constant for subcircuits, so they need to be copied from the base model.
for( int i = 0; i < GetBaseModel()->GetPinCount(); ++i )
AddPin( GetBaseModel()->GetPin( i ) );
// Same for parameters.
for( int i = 0; i < GetBaseModel()->GetParamCount(); ++i )
AddParam( GetBaseModel()->GetParam( i ).info );
}

View File

@ -28,10 +28,18 @@
#include <sim/sim_model.h>
class SIM_MODEL_SUBCIRCUIT : public SIM_MODEL
class SIM_MODEL_SUBCKT : public SIM_MODEL
{
public:
SIM_MODEL_SUBCIRCUIT( TYPE aType );
SIM_MODEL_SUBCKT( TYPE aType );
bool ReadSpiceCode( const std::string& aSpiceCode ) override;
wxString GenerateSpiceModelLine( const wxString& aModelName ) const;
std::vector<wxString> GenerateSpiceCurrentNames( const wxString& aRefName ) const override;
void SetBaseModel( const SIM_MODEL& aBaseModel ) override;
private:
std::vector<std::unique_ptr<PARAM::INFO>> m_paramInfos;
};
#endif // SIM_MODEL_SUBCIRCUIT_H

View File

@ -22,10 +22,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <sim/sim_model_codemodel.h>
#include <sim/sim_model_xspice.h>
SIM_MODEL_CODEMODEL::SIM_MODEL_CODEMODEL( TYPE aType )
SIM_MODEL_XSPICE::SIM_MODEL_XSPICE( TYPE aType )
: SIM_MODEL( aType )
{
}

View File

@ -28,10 +28,10 @@
#include <sim/sim_model.h>
class SIM_MODEL_CODEMODEL : public SIM_MODEL
class SIM_MODEL_XSPICE : public SIM_MODEL
{
public:
SIM_MODEL_CODEMODEL( TYPE aType );
SIM_MODEL_XSPICE( TYPE aType );
};
#endif // SIM_MODEL_CODEMODEL_H

View File

@ -467,7 +467,10 @@ void SIM_PLOT_FRAME::StartSimulation( const wxString& aSimCommand )
else
m_circuitModel->SetSimCommand( aSimCommand );
m_circuitModel->SetOptions( m_settingsDlg->GetNetlistOptions() );
// Make .save all and .probe alli permanent for now.
m_circuitModel->SetOptions( m_settingsDlg->GetNetlistOptions()
| NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES
| NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS );
if( !m_simulator->Attach( m_circuitModel ) )
{
@ -523,13 +526,13 @@ SIM_PANEL_BASE* SIM_PLOT_FRAME::NewPlotPanel( wxString aSimCommand )
void SIM_PLOT_FRAME::AddVoltagePlot( const wxString& aNetName )
{
addPlot( aNetName, SPT_VOLTAGE, "V" );
addPlot( aNetName, SPT_VOLTAGE );
}
void SIM_PLOT_FRAME::AddCurrentPlot( const wxString& aDeviceName, const wxString& aParam )
void SIM_PLOT_FRAME::AddCurrentPlot( const wxString& aDeviceName )
{
addPlot( aDeviceName, SPT_CURRENT, aParam );
addPlot( aDeviceName, SPT_CURRENT );
}
@ -540,12 +543,20 @@ void SIM_PLOT_FRAME::AddTuner( SCH_SYMBOL* aSymbol )
if( !plotPanel )
return;
// For now limit the tuner tool to RLC and code model components
char primitiveType = NETLIST_EXPORTER_PSPICE::GetSpiceField( SF_PRIMITIVE, aSymbol, 0 )[0];
SIM_MODEL::TYPE type = SIM_MODEL::ReadTypeFromFields( aSymbol->GetFields() );
SIM_MODEL::DEVICE_TYPE deviceType = SIM_MODEL::TypeInfo( type ).deviceType;
if( primitiveType != SP_RESISTOR && primitiveType != SP_CAPACITOR
&& primitiveType != SP_INDUCTOR && primitiveType != SP_CODEMODEL )
switch( deviceType )
{
case SIM_MODEL::DEVICE_TYPE::R:
case SIM_MODEL::DEVICE_TYPE::C:
case SIM_MODEL::DEVICE_TYPE::L:
case SIM_MODEL::DEVICE_TYPE::XSPICE:
break;
default:
return;
}
const wxString componentName = aSymbol->GetField( REFERENCE_FIELD )->GetText();
@ -629,7 +640,7 @@ std::shared_ptr<SPICE_SIMULATOR_SETTINGS>& SIM_PLOT_FRAME::GetSimulatorSettings(
}
void SIM_PLOT_FRAME::addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam )
void SIM_PLOT_FRAME::addPlot( const wxString& aName, SIM_PLOT_TYPE aType )
{
SIM_TYPE simType = m_circuitModel->GetSimType();
@ -668,14 +679,12 @@ void SIM_PLOT_FRAME::addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const
int baseType = aType & ~( SPT_AC_MAG | SPT_AC_PHASE );
// Add two plots: magnitude & phase
updated |= updatePlot( aName, ( SIM_PLOT_TYPE )( baseType | SPT_AC_MAG ), aParam,
plotPanel );
updated |= updatePlot( aName, ( SIM_PLOT_TYPE )( baseType | SPT_AC_PHASE ), aParam,
plotPanel );
updated |= updatePlot( aName, ( SIM_PLOT_TYPE )( baseType | SPT_AC_MAG ), plotPanel );
updated |= updatePlot( aName, ( SIM_PLOT_TYPE )( baseType | SPT_AC_PHASE ), plotPanel );
}
else
{
updated = updatePlot( aName, aType, aParam, plotPanel );
updated = updatePlot( aName, aType, plotPanel );
}
if( updated )
@ -702,13 +711,12 @@ void SIM_PLOT_FRAME::removePlot( const wxString& aPlotName )
}
bool SIM_PLOT_FRAME::updatePlot( const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam,
bool SIM_PLOT_FRAME::updatePlot( const wxString& aName, SIM_PLOT_TYPE aType,
SIM_PLOT_PANEL* aPlotPanel )
{
SIM_TYPE simType = m_circuitModel->GetSimType();
wxString spiceVector = m_circuitModel->ComponentToVector( aName, aType, aParam );
wxString plotTitle = wxString::Format( "%s(%s)", aParam, aName );
wxString plotTitle = aName;
if( aType & SPT_AC_MAG )
plotTitle += " (mag)";
else if( aType & SPT_AC_PHASE )
@ -717,7 +725,7 @@ bool SIM_PLOT_FRAME::updatePlot( const wxString& aName, SIM_PLOT_TYPE aType, con
if( !SIM_PANEL_BASE::IsPlottable( simType ) )
{
// There is no plot to be shown
m_simulator->Command( wxString::Format( "print %s", spiceVector ).ToStdString() );
m_simulator->Command( wxString::Format( "print %s", aName ).ToStdString() );
return false;
}
@ -744,9 +752,9 @@ bool SIM_PLOT_FRAME::updatePlot( const wxString& aName, SIM_PLOT_TYPE aType, con
"Cannot set both AC_PHASE and AC_MAG bits" );
if( aType & SPT_AC_MAG )
data_y = m_simulator->GetMagPlot( (const char*) spiceVector.c_str() );
data_y = m_simulator->GetMagPlot( (const char*) aName.c_str() );
else if( aType & SPT_AC_PHASE )
data_y = m_simulator->GetPhasePlot( (const char*) spiceVector.c_str() );
data_y = m_simulator->GetPhasePlot( (const char*) aName.c_str() );
else
wxASSERT_MSG( false, "Plot type missing AC_PHASE or AC_MAG bit" );
@ -755,7 +763,7 @@ bool SIM_PLOT_FRAME::updatePlot( const wxString& aName, SIM_PLOT_TYPE aType, con
case ST_NOISE:
case ST_DC:
case ST_TRANSIENT:
data_y = m_simulator->GetMagPlot( (const char*) spiceVector.c_str() );
data_y = m_simulator->GetMagPlot( (const char*) aName.c_str() );
break;
default:
@ -796,7 +804,7 @@ bool SIM_PLOT_FRAME::updatePlot( const wxString& aName, SIM_PLOT_TYPE aType, con
data_y.begin() + offset + inner );
m_workbook->AddTrace( aPlotPanel, name, aName, inner, sub_x.data(), sub_y.data(),
aType, aParam );
aType );
v = v + source2.m_vincrement;
offset += inner;
@ -806,8 +814,7 @@ bool SIM_PLOT_FRAME::updatePlot( const wxString& aName, SIM_PLOT_TYPE aType, con
}
}
m_workbook->AddTrace( aPlotPanel, plotTitle, aName, size, data_x.data(), data_y.data(), aType,
aParam );
m_workbook->AddTrace( aPlotPanel, plotTitle, aName, size, data_x.data(), data_y.data(), aType );
return true;
}
@ -881,7 +888,7 @@ void SIM_PLOT_FRAME::updateSignalList()
void SIM_PLOT_FRAME::updateTuners()
{
const auto& spiceItems = m_circuitModel->GetSpiceItems();
const auto& spiceItems = m_circuitModel->GetItems();
for( auto it = m_tuners.begin(); it != m_tuners.end(); /* iteration inside the loop */ )
{
@ -889,7 +896,7 @@ void SIM_PLOT_FRAME::updateTuners()
if( std::find_if( spiceItems.begin(), spiceItems.end(), [&]( const SPICE_ITEM& item )
{
return item.m_refName == ref;
return item.refName == ref;
}) == spiceItems.end() )
{
// The component does not exist anymore, remove the associated tuner
@ -1008,7 +1015,7 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath )
return false;
}
addPlot( name, (SIM_PLOT_TYPE) traceType, param );
addPlot( name, (SIM_PLOT_TYPE) traceType );
}
}
@ -1467,7 +1474,7 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
if( !m_settingsDlg )
m_settingsDlg = new DIALOG_SIM_SETTINGS( this, m_circuitModel, m_simulator->Settings() );
if( !m_circuitModel->ProcessNetlist( NET_ALL_FLAGS ) )
if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_ALL_FLAGS ) )
{
DisplayErrorMessage( this, _( "There were errors during netlist export, aborted." ) );
return;
@ -1747,7 +1754,6 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
{
wxString m_name; ///< Name of the measured net/device
SIM_PLOT_TYPE m_type; ///< Type of the signal
wxString m_param; ///< Name of the signal parameter
};
std::vector<struct TRACE_DESC> traceInfo;
@ -1758,14 +1764,13 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
struct TRACE_DESC placeholder;
placeholder.m_name = trace.second->GetName();
placeholder.m_type = trace.second->GetType();
placeholder.m_param = trace.second->GetParam();
traceInfo.push_back( placeholder );
}
for( auto& trace : traceInfo )
{
if( !updatePlot( trace.m_name, trace.m_type, trace.m_param, plotPanel ) )
if( !updatePlot( trace.m_name, trace.m_type, plotPanel ) )
removePlot( trace.m_name );
}

View File

@ -92,7 +92,7 @@ public:
* @param aDeviceName is the device name (e.g. R1, C1).
* @param aParam is the current type (e.g. I, Ic, Id).
*/
void AddCurrentPlot( const wxString& aDeviceName, const wxString& aParam );
void AddCurrentPlot( const wxString& aDeviceName );
/**
* Add a tuner for a symbol.
@ -169,7 +169,7 @@ private:
* @param aType describes the type of plot.
* @param aParam is the parameter for the device/net (e.g. I, Id, V).
*/
void addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam );
void addPlot( const wxString& aName, SIM_PLOT_TYPE aType );
/**
* Remove a plot with a specific title.
@ -188,8 +188,7 @@ private:
* @param aPlotPanel is the panel that should receive the update.
* @return True if a plot was successfully added/updated.
*/
bool updatePlot( const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam,
SIM_PLOT_PANEL* aPlotPanel );
bool updatePlot( const wxString& aName, SIM_PLOT_TYPE aType, SIM_PLOT_PANEL* aPlotPanel );
/**
* Update the list of currently plotted signals.

View File

@ -470,8 +470,7 @@ void SIM_PLOT_PANEL::UpdateTraceStyle( TRACE* trace )
bool SIM_PLOT_PANEL::addTrace( const wxString& aTitle, const wxString& aName, int aPoints,
const double* aX, const double* aY, SIM_PLOT_TYPE aType,
const wxString& aParam )
const double* aX, const double* aY, SIM_PLOT_TYPE aType )
{
TRACE* trace = nullptr;
wxString name = aTitle;
@ -504,7 +503,7 @@ bool SIM_PLOT_PANEL::addTrace( const wxString& aTitle, const wxString& aName, in
}
// New entry
trace = new TRACE( aName, aType, aParam );
trace = new TRACE( aName, aType );
trace->SetTraceColour( m_colors.GenerateColor( m_traces ) );
UpdateTraceStyle( trace );
m_traces[name] = trace;

View File

@ -94,8 +94,8 @@ private:
class TRACE : public mpFXYVector
{
public:
TRACE( const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam ) :
mpFXYVector( aName ), m_cursor( nullptr ), m_type( aType ), m_param( aParam )
TRACE( const wxString& aName, SIM_PLOT_TYPE aType ) :
mpFXYVector( aName ), m_cursor( nullptr ), m_type( aType )
{
SetContinuity( true );
SetDrawOutsideMargins( false );
@ -291,7 +291,7 @@ public:
protected:
bool addTrace( const wxString& aTitle, const wxString& aName, int aPoints, const double* aX,
const double* aY, SIM_PLOT_TYPE aType, const wxString& aParam );
const double* aY, SIM_PLOT_TYPE aType );
bool deleteTrace( const wxString& aName );

View File

@ -37,7 +37,7 @@ wxBEGIN_EVENT_TABLE( SIM_VALIDATOR, wxValidator )
wxEND_EVENT_TABLE()
SIM_VALIDATOR::SIM_VALIDATOR( SIM_VALUE_BASE::TYPE aValueType,
SIM_VALIDATOR::SIM_VALIDATOR( SIM_VALUE::TYPE aValueType,
SIM_VALUE_GRAMMAR::NOTATION aNotation )
: wxValidator(),
m_valueType( aValueType ),
@ -154,7 +154,7 @@ SIM_PROPERTY::SIM_PROPERTY( const wxString& aLabel, const wxString& aName,
std::shared_ptr<SIM_LIBRARY> aLibrary,
std::shared_ptr<SIM_MODEL> aModel,
int aParamIndex,
SIM_VALUE_BASE::TYPE aValueType,
SIM_VALUE::TYPE aValueType,
SIM_VALUE_GRAMMAR::NOTATION aNotation )
: wxStringProperty( aLabel, aName ),
m_valueType( aValueType ),
@ -175,26 +175,23 @@ wxValidator* SIM_PROPERTY::DoGetValidator() const
bool SIM_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags ) const
{
try
{
wxString paramValueStr = m_model->GetBaseParam( m_paramIndex ).value->ToString();
wxString paramValueStr = m_model->GetBaseParam( m_paramIndex ).value->ToString();
aVariant = aText;
// TODO: Don't use string comparison.
if( m_model->GetBaseModel() && ( aText.IsEmpty() || aText == paramValueStr ) )
{
m_model->SetParamValue( m_paramIndex, "" ); // Nullify.
aVariant = paramValueStr; // Use the inherited value (if it exists) if null.
}
else
{
m_model->SetParamValue( m_paramIndex, aText );
aVariant = GetParam().value->ToString();
}
}
catch( KI_PARAM_ERROR& e )
// TODO: Don't use string comparison.
if( m_model->GetBaseModel() && ( aText.IsEmpty() || aText == paramValueStr ) )
{
aVariant = aText;
return false;
if( !m_model->SetParamValue( m_paramIndex, "" ) ) // Nullify.
return false;
aVariant = paramValueStr; // Use the inherited value (if it exists) if null.
}
else
{
if( !m_model->SetParamValue( m_paramIndex, aText ) )
return false;
aVariant = GetParam().value->ToString();
}
return true;

View File

@ -32,7 +32,7 @@
class SIM_VALIDATOR : public wxValidator
{
public:
SIM_VALIDATOR( SIM_VALUE_BASE::TYPE aValueType, SIM_VALUE_GRAMMAR::NOTATION aNotation );
SIM_VALIDATOR( SIM_VALUE::TYPE aValueType, SIM_VALUE_GRAMMAR::NOTATION aNotation );
SIM_VALIDATOR( const SIM_VALIDATOR& aValidator ) = default;
wxObject* Clone() const override;
@ -50,7 +50,7 @@ private:
void onChar( wxKeyEvent& aEvent );
void onMouse( wxMouseEvent& aEvent );
SIM_VALUE_BASE::TYPE m_valueType;
SIM_VALUE::TYPE m_valueType;
SIM_VALUE_GRAMMAR::NOTATION m_notation;
wxString m_prevText;
long m_prevInsertionPoint;
@ -68,7 +68,7 @@ public:
std::shared_ptr<SIM_LIBRARY> aLibrary,
std::shared_ptr<SIM_MODEL> aModel,
int aParamIndex,
SIM_VALUE_BASE::TYPE aValueType = SIM_VALUE_BASE::TYPE::FLOAT,
SIM_VALUE::TYPE aValueType = SIM_VALUE::TYPE::FLOAT,
SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI );
wxValidator* DoGetValidator() const override;
@ -79,7 +79,7 @@ public:
const SIM_MODEL::PARAM& GetParam() const { return m_model->GetParam( m_paramIndex ); }
protected:
SIM_VALUE_BASE::TYPE m_valueType;
SIM_VALUE::TYPE m_valueType;
SIM_VALUE_GRAMMAR::NOTATION m_notation;
std::shared_ptr<SIM_LIBRARY> m_library;
std::shared_ptr<SIM_MODEL> m_model;

View File

@ -33,40 +33,40 @@
#define CALL_INSTANCE( ValueType, Notation, func, ... ) \
switch( ValueType ) \
{ \
case SIM_VALUE_BASE::TYPE::INT: \
case SIM_VALUE::TYPE::INT: \
switch( Notation ) \
{ \
case NOTATION::SI: \
func<SIM_VALUE_BASE::TYPE::INT, NOTATION::SI>( __VA_ARGS__ ); \
func<SIM_VALUE::TYPE::INT, NOTATION::SI>( __VA_ARGS__ ); \
break; \
\
case NOTATION::SPICE: \
func<SIM_VALUE_BASE::TYPE::INT, NOTATION::SPICE>( __VA_ARGS__ ); \
func<SIM_VALUE::TYPE::INT, NOTATION::SPICE>( __VA_ARGS__ ); \
break; \
} \
break; \
\
case SIM_VALUE_BASE::TYPE::FLOAT: \
case SIM_VALUE::TYPE::FLOAT: \
switch( Notation ) \
{ \
case NOTATION::SI: \
func<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SI>( __VA_ARGS__ ); \
func<SIM_VALUE::TYPE::FLOAT, NOTATION::SI>( __VA_ARGS__ ); \
break; \
\
case NOTATION::SPICE: \
func<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SPICE>( __VA_ARGS__ ); \
func<SIM_VALUE::TYPE::FLOAT, NOTATION::SPICE>( __VA_ARGS__ ); \
break; \
} \
break; \
\
case SIM_VALUE_BASE::TYPE::BOOL: \
case SIM_VALUE_BASE::TYPE::COMPLEX: \
case SIM_VALUE_BASE::TYPE::STRING: \
case SIM_VALUE_BASE::TYPE::BOOL_VECTOR: \
case SIM_VALUE_BASE::TYPE::INT_VECTOR: \
case SIM_VALUE_BASE::TYPE::FLOAT_VECTOR: \
case SIM_VALUE_BASE::TYPE::COMPLEX_VECTOR: \
wxFAIL_MSG( "Unhandled SIM_VALUE_BASE type" ); \
case SIM_VALUE::TYPE::BOOL: \
case SIM_VALUE::TYPE::COMPLEX: \
case SIM_VALUE::TYPE::STRING: \
case SIM_VALUE::TYPE::BOOL_VECTOR: \
case SIM_VALUE::TYPE::INT_VECTOR: \
case SIM_VALUE::TYPE::FLOAT_VECTOR: \
case SIM_VALUE::TYPE::COMPLEX_VECTOR: \
wxFAIL_MSG( "Unhandled SIM_VALUE type" ); \
break; \
}
@ -78,24 +78,27 @@ namespace SIM_VALUE_PARSER
template <typename Rule>
struct numberSelector : std::false_type {};
template <> struct numberSelector<SIM_VALUE_GRAMMAR::significand<SIM_VALUE_BASE::TYPE::INT>>
// TODO: Reorder. NOTATION should be before TYPE.
template <> struct numberSelector<SIM_VALUE_GRAMMAR::significand<SIM_VALUE::TYPE::INT>>
: std::true_type {};
template <> struct numberSelector<SIM_VALUE_GRAMMAR::significand<SIM_VALUE_BASE::TYPE::FLOAT>>
template <> struct numberSelector<SIM_VALUE_GRAMMAR::significand<SIM_VALUE::TYPE::FLOAT>>
: std::true_type {};
template <> struct numberSelector<intPart> : std::true_type {};
template <> struct numberSelector<fracPart> : std::true_type {};
template <> struct numberSelector<exponent> : std::true_type {};
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::INT, NOTATION::SI>>
template <> struct numberSelector<metricSuffix<SIM_VALUE::TYPE::INT, NOTATION::SI>>
: std::true_type {};
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::INT, NOTATION::SPICE>>
template <> struct numberSelector<metricSuffix<SIM_VALUE::TYPE::INT, NOTATION::SPICE>>
: std::true_type {};
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SI>>
template <> struct numberSelector<metricSuffix<SIM_VALUE::TYPE::FLOAT, NOTATION::SI>>
: std::true_type {};
template <> struct numberSelector<metricSuffix<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SPICE>>
template <> struct numberSelector<metricSuffix<SIM_VALUE::TYPE::FLOAT, NOTATION::SPICE>>
: std::true_type {};
struct PARSE_RESULT
{
bool isOk = true;
bool isEmpty = true;
std::string significand;
OPT<long> intPart;
@ -105,8 +108,8 @@ namespace SIM_VALUE_PARSER
};
PARSE_RESULT Parse( const wxString& aString,
SIM_VALUE_BASE::TYPE aValueType = SIM_VALUE_BASE::TYPE::FLOAT,
NOTATION aNotation = NOTATION::SI );
NOTATION aNotation = NOTATION::SI,
SIM_VALUE::TYPE aValueType = SIM_VALUE::TYPE::FLOAT );
long MetricSuffixToExponent( std::string aMetricSuffix, NOTATION aNotation = NOTATION::SI );
wxString ExponentToMetricSuffix( double aExponent, long& aReductionExponent,
@ -114,23 +117,24 @@ namespace SIM_VALUE_PARSER
}
template <SIM_VALUE_BASE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
template <SIM_VALUE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
static inline void doIsValid( tao::pegtl::string_input<>& aIn )
{
tao::pegtl::parse<SIM_VALUE_PARSER::numberGrammar<ValueType, Notation>>( aIn );
}
bool SIM_VALUE_GRAMMAR::IsValid( const wxString& aString,
SIM_VALUE_BASE::TYPE aValueType,
SIM_VALUE::TYPE aValueType,
NOTATION aNotation )
{
tao::pegtl::string_input<> in( aString, "from_input" );
tao::pegtl::string_input<> in( aString.ToStdString(), "from_content" );
try
{
CALL_INSTANCE( aValueType, aNotation, doIsValid, in );
}
catch( tao::pegtl::parse_error& e )
catch( const tao::pegtl::parse_error& e )
{
return false;
}
@ -139,7 +143,7 @@ bool SIM_VALUE_GRAMMAR::IsValid( const wxString& aString,
}
template <SIM_VALUE_BASE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
template <SIM_VALUE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
static inline std::unique_ptr<tao::pegtl::parse_tree::node> doParse(
tao::pegtl::string_input<>& aIn )
{
@ -148,7 +152,8 @@ static inline std::unique_ptr<tao::pegtl::parse_tree::node> doParse(
( aIn );
}
template <SIM_VALUE_BASE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
template <SIM_VALUE::TYPE ValueType, SIM_VALUE_PARSER::NOTATION Notation>
static inline void handleNodeForParse( tao::pegtl::parse_tree::node& aNode,
SIM_VALUE_PARSER::PARSE_RESULT& aParseResult )
{
@ -180,14 +185,16 @@ static inline void handleNodeForParse( tao::pegtl::parse_tree::node& aNode,
wxFAIL_MSG( "Unhandled parse tree node" );
}
SIM_VALUE_PARSER::PARSE_RESULT SIM_VALUE_PARSER::Parse( const wxString& aString,
SIM_VALUE_BASE::TYPE aValueType,
NOTATION aNotation )
NOTATION aNotation,
SIM_VALUE::TYPE aValueType )
{
LOCALE_IO toggle;
tao::pegtl::string_input<> in( aString.ToStdString(), "from_input" );
tao::pegtl::string_input<> in( aString.ToStdString(), "from_content" );
std::unique_ptr<tao::pegtl::parse_tree::node> root;
PARSE_RESULT result;
try
{
@ -195,14 +202,12 @@ SIM_VALUE_PARSER::PARSE_RESULT SIM_VALUE_PARSER::Parse( const wxString& aString,
}
catch( tao::pegtl::parse_error& e )
{
throw KI_PARAM_ERROR( wxString::Format( _( "Failed to parse '%s': %s" ), aString,
e.what() ) );
result.isOk = false;
return result;
}
wxASSERT( root );
PARSE_RESULT result;
try
{
for( const auto& node : root->children )
@ -212,8 +217,8 @@ SIM_VALUE_PARSER::PARSE_RESULT SIM_VALUE_PARSER::Parse( const wxString& aString,
}
catch( std::invalid_argument& e )
{
throw KI_PARAM_ERROR( wxString::Format( _( "Failed to parse '%s': %s" ), aString,
e.what() ) );
wxFAIL_MSG( wxString::Format( "Parsing simulator value failed: %s", e.what() ) );
result.isOk = false;
}
return result;
@ -275,8 +280,8 @@ long SIM_VALUE_PARSER::MetricSuffixToExponent( std::string aMetricSuffix, NOTATI
break;
}
throw KI_PARAM_ERROR( wxString::Format( _( "Unknown simulator value suffix: \"%s\"" ),
aMetricSuffix ) );
wxFAIL_MSG( wxString::Format( "Unknown simulator value suffix: '%s'", aMetricSuffix ) );
return 0;
}
@ -354,27 +359,27 @@ wxString SIM_VALUE_PARSER::ExponentToMetricSuffix( double aExponent, long& aRedu
}
std::unique_ptr<SIM_VALUE_BASE> SIM_VALUE_BASE::Create( TYPE aType, wxString aString )
std::unique_ptr<SIM_VALUE> SIM_VALUE::Create( TYPE aType, wxString aString )
{
std::unique_ptr<SIM_VALUE_BASE> value = SIM_VALUE_BASE::Create( aType );
std::unique_ptr<SIM_VALUE> value = SIM_VALUE::Create( aType );
value->FromString( aString );
return value;
}
std::unique_ptr<SIM_VALUE_BASE> SIM_VALUE_BASE::Create( TYPE aType )
std::unique_ptr<SIM_VALUE> SIM_VALUE::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>>>();
case TYPE::BOOL: return std::make_unique<SIM_VALUE_INSTANCE<bool>>();
case TYPE::INT: return std::make_unique<SIM_VALUE_INSTANCE<long>>();
case TYPE::FLOAT: return std::make_unique<SIM_VALUE_INSTANCE<double>>();
case TYPE::COMPLEX: return std::make_unique<SIM_VALUE_INSTANCE<std::complex<double>>>();
case TYPE::STRING: return std::make_unique<SIM_VALUE_INSTANCE<wxString>>();
case TYPE::BOOL_VECTOR: return std::make_unique<SIM_VALUE_INSTANCE<bool>>();
case TYPE::INT_VECTOR: return std::make_unique<SIM_VALUE_INSTANCE<long>>();
case TYPE::FLOAT_VECTOR: return std::make_unique<SIM_VALUE_INSTANCE<double>>();
case TYPE::COMPLEX_VECTOR: return std::make_unique<SIM_VALUE_INSTANCE<std::complex<double>>>();
}
wxFAIL_MSG( _( "Unknown SIM_VALUE type" ) );
@ -382,28 +387,29 @@ std::unique_ptr<SIM_VALUE_BASE> SIM_VALUE_BASE::Create( TYPE aType )
}
void SIM_VALUE_BASE::operator=( const wxString& aString )
void SIM_VALUE::operator=( const wxString& aString )
{
FromString( aString );
}
template <typename T>
SIM_VALUE<T>::SIM_VALUE( const T& aValue ) : m_value( aValue )
SIM_VALUE_INSTANCE<T>::SIM_VALUE_INSTANCE( const T& aValue ) : m_value( aValue )
{
}
template <>
void SIM_VALUE<bool>::FromString( const wxString& aString )
bool SIM_VALUE_INSTANCE<bool>::FromString( const wxString& aString, NOTATION aNotation )
{
SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( aString );
SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( aString, aNotation );
m_value = NULLOPT;
if( !parseResult.isOk )
return false;
if( parseResult.isEmpty )
{
m_value = NULLOPT;
return;
}
return true;
if( !parseResult.intPart
|| ( *parseResult.intPart != 0 && *parseResult.intPart != 1 )
@ -411,65 +417,73 @@ void SIM_VALUE<bool>::FromString( const wxString& aString )
|| parseResult.exponent
|| parseResult.metricSuffixExponent )
{
throw KI_PARAM_ERROR( wxString::Format( _( "Invalid Bool simulator value string: '%s'" ),
aString ) );
return false;
}
m_value = *parseResult.intPart;
return true;
}
template <>
void SIM_VALUE<long>::FromString( const wxString& aString )
bool SIM_VALUE_INSTANCE<long>::FromString( const wxString& aString, NOTATION aNotation )
{
SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( aString );
SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( aString, aNotation );
m_value = NULLOPT;
if( !parseResult.isOk )
return false;
if( parseResult.isEmpty )
{
m_value = NULLOPT;
return;
}
return true;
if( !parseResult.intPart || parseResult.fracPart )
{
throw KI_PARAM_ERROR( wxString::Format( _( "Invalid Int simulator value string: '%s'" ),
aString ) );
}
return false;
long exponent = parseResult.exponent ? *parseResult.exponent : 0;
exponent += parseResult.metricSuffixExponent ? *parseResult.metricSuffixExponent : 0;
m_value = static_cast<double>( *parseResult.intPart ) * std::pow( 10, exponent );
return true;
}
template <>
void SIM_VALUE<double>::FromString( const wxString& aString )
bool SIM_VALUE_INSTANCE<double>::FromString( const wxString& aString, NOTATION aNotation )
{
SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( aString );
SIM_VALUE_PARSER::PARSE_RESULT parseResult = SIM_VALUE_PARSER::Parse( aString, aNotation );
m_value = NULLOPT;
if( !parseResult.isOk )
return false;
if( parseResult.isEmpty )
return true;
// Single dot should be allowed in fields.
// TODO: disallow single dot in models.
if( parseResult.isEmpty || parseResult.significand == "." )
{
m_value = NULLOPT;
return;
}
if( parseResult.significand.empty() )
throw KI_PARAM_ERROR( wxString::Format( _( "Invalid Float simulator value string: '%s'" ),
aString ) );
if( parseResult.significand.empty() || parseResult.significand == "." )
return false;
long exponent = parseResult.exponent ? *parseResult.exponent : 0;
exponent += parseResult.metricSuffixExponent ? *parseResult.metricSuffixExponent : 0;
m_value = std::stod( parseResult.significand ) * std::pow( 10, exponent );
try
{
m_value = std::stod( parseResult.significand ) * std::pow( 10, exponent );
}
catch( const std::invalid_argument& e )
{
return false;
}
return true;
}
template <>
void SIM_VALUE<std::complex<double>>::FromString( const wxString& aString )
bool SIM_VALUE_INSTANCE<std::complex<double>>::FromString( const wxString& aString,
NOTATION aNotation )
{
// TODO
@ -481,18 +495,20 @@ void SIM_VALUE<std::complex<double>>::FromString( const wxString& aString )
throw KI_PARAM_ERROR( _( "Invalid complex sim value string" ) );
m_value = value;*/
return true;
}
template <>
void SIM_VALUE<wxString>::FromString( const wxString& aString )
bool SIM_VALUE_INSTANCE<wxString>::FromString( const wxString& aString, NOTATION aNotation )
{
m_value = aString;
return true;
}
template <typename T>
wxString SIM_VALUE<T>::ToString() const
wxString SIM_VALUE_INSTANCE<T>::ToString( NOTATION aNotation ) const
{
static_assert( std::is_same<T, std::vector<T>>::value );
@ -500,7 +516,7 @@ wxString SIM_VALUE<T>::ToString() const
for( auto it = m_value.cbegin(); it != m_value.cend(); it++ )
{
string += SIM_VALUE<T>( *it ).ToString();
string += SIM_VALUE_INSTANCE<T>( *it ).ToString();
string += ",";
}
@ -509,7 +525,7 @@ wxString SIM_VALUE<T>::ToString() const
template <>
wxString SIM_VALUE<bool>::ToString() const
wxString SIM_VALUE_INSTANCE<bool>::ToString( NOTATION aNotation ) const
{
LOCALE_IO toggle;
@ -521,7 +537,7 @@ wxString SIM_VALUE<bool>::ToString() const
template <>
wxString SIM_VALUE<long>::ToString() const
wxString SIM_VALUE_INSTANCE<long>::ToString( NOTATION aNotation ) const
{
LOCALE_IO toggle;
@ -538,7 +554,7 @@ wxString SIM_VALUE<long>::ToString() const
long dummy = 0;
wxString metricSuffix = SIM_VALUE_PARSER::ExponentToMetricSuffix(
static_cast<double>( exponent ), dummy );
static_cast<double>( exponent ), dummy, aNotation );
return wxString::Format( "%d%s", value, metricSuffix );
}
@ -547,7 +563,7 @@ wxString SIM_VALUE<long>::ToString() const
template <>
wxString SIM_VALUE<double>::ToString() const
wxString SIM_VALUE_INSTANCE<double>::ToString( NOTATION aNotation ) const
{
LOCALE_IO toggle;
@ -568,7 +584,7 @@ wxString SIM_VALUE<double>::ToString() const
template <>
wxString SIM_VALUE<std::complex<double>>::ToString() const
wxString SIM_VALUE_INSTANCE<std::complex<double>>::ToString( NOTATION aNotation ) const
{
LOCALE_IO toggle;
@ -580,7 +596,7 @@ wxString SIM_VALUE<std::complex<double>>::ToString() const
template <>
wxString SIM_VALUE<wxString>::ToString() const
wxString SIM_VALUE_INSTANCE<wxString>::ToString( NOTATION aNotation ) const
{
LOCALE_IO toggle;
@ -592,7 +608,7 @@ wxString SIM_VALUE<wxString>::ToString() const
template <typename T>
wxString SIM_VALUE<T>::ToSimpleString() const
wxString SIM_VALUE_INSTANCE<T>::ToSimpleString() const
{
if( m_value.has_value() )
{
@ -606,7 +622,7 @@ wxString SIM_VALUE<T>::ToSimpleString() const
template <>
wxString SIM_VALUE<std::complex<double>>::ToSimpleString() const
wxString SIM_VALUE_INSTANCE<std::complex<double>>::ToSimpleString() const
{
// TODO
@ -619,9 +635,9 @@ wxString SIM_VALUE<std::complex<double>>::ToSimpleString() const
template <typename T>
bool SIM_VALUE<T>::operator==( const SIM_VALUE_BASE& aOther ) const
bool SIM_VALUE_INSTANCE<T>::operator==( const SIM_VALUE& aOther ) const
{
const SIM_VALUE* otherNumber = dynamic_cast<const SIM_VALUE*>( &aOther );
const SIM_VALUE_INSTANCE* otherNumber = dynamic_cast<const SIM_VALUE_INSTANCE*>( &aOther );
if( otherNumber )
return m_value == otherNumber->m_value;

View File

@ -31,9 +31,23 @@
#include <pegtl.hpp>
class SIM_VALUE_BASE
namespace SIM_VALUE_GRAMMAR
{
using namespace tao::pegtl;
enum class NOTATION
{
SI,
SPICE
};
}
class SIM_VALUE
{
public:
using NOTATION = SIM_VALUE_GRAMMAR::NOTATION;
enum class TYPE
{
BOOL,
@ -48,17 +62,17 @@ public:
COMPLEX_VECTOR
};
static std::unique_ptr<SIM_VALUE_BASE> Create( TYPE aType, wxString aString );
static std::unique_ptr<SIM_VALUE_BASE> Create( TYPE aType );
static std::unique_ptr<SIM_VALUE> Create( TYPE aType, wxString aString );
static std::unique_ptr<SIM_VALUE> Create( TYPE aType );
virtual ~SIM_VALUE_BASE() = default;
SIM_VALUE_BASE() = default;
virtual ~SIM_VALUE() = default;
SIM_VALUE() = default;
void operator=( const wxString& aString );
virtual bool operator==( const SIM_VALUE_BASE& aOther ) const = 0;
virtual bool operator==( const SIM_VALUE& aOther ) const = 0;
virtual void FromString( const wxString& aString ) = 0;
virtual wxString ToString() const = 0;
virtual bool FromString( const wxString& aString, NOTATION aNotation = NOTATION::SI ) = 0;
virtual wxString ToString( NOTATION aNotation = NOTATION::SI ) const = 0;
// For parsers that don't accept strings with our suffixes.
virtual wxString ToSimpleString() const = 0;
@ -66,36 +80,29 @@ public:
template <typename T>
class SIM_VALUE : public SIM_VALUE_BASE
class SIM_VALUE_INSTANCE : public SIM_VALUE
{
public:
SIM_VALUE() = default;
SIM_VALUE( const T& aValue );
SIM_VALUE_INSTANCE() = default;
SIM_VALUE_INSTANCE( const T& aValue );
void FromString( const wxString& aString ) override;
wxString ToString() const override;
// TODO: Don't pass aNotation. Make a FromSpiceString() function instead.
bool FromString( const wxString& aString, NOTATION aNotation = NOTATION::SI ) override;
wxString ToString( NOTATION aNotation = NOTATION::SI ) const override;
wxString ToSimpleString() const override;
void operator=( const T& aValue );
bool operator==( const SIM_VALUE_BASE& aOther ) const override;
bool operator==( const SIM_VALUE& aOther ) const override;
private:
OPT<T> m_value = NULLOPT;
wxString getMetricSuffix();
OPT<T> m_value = NULLOPT;
};
namespace SIM_VALUE_GRAMMAR
{
using namespace tao::pegtl;
enum class NOTATION
{
SI,
SPICE
};
template <NOTATION Notation>
wxString allowedIntChars;
@ -111,17 +118,17 @@ namespace SIM_VALUE_GRAMMAR
//struct fracPartWithPrefix : seq<fracPartPrefix, fracPart> {};
template <SIM_VALUE_BASE::TYPE ValueType>
template <SIM_VALUE::TYPE ValueType>
struct significand;
template <> struct significand<SIM_VALUE_BASE::TYPE::FLOAT> :
template <> struct significand<SIM_VALUE::TYPE::FLOAT> :
sor<seq<intPart, one<'.'>, fracPart>,
seq<intPart, one<'.'>>,
intPart,
seq<one<'.'>, fracPart>,
one<'.'>> {};
template <> struct significand<SIM_VALUE_BASE::TYPE::INT> : intPart {};
template <> struct significand<SIM_VALUE::TYPE::INT> : intPart {};
struct exponentPrefix : one<'e', 'E'> {};
@ -129,20 +136,20 @@ namespace SIM_VALUE_GRAMMAR
struct exponentWithPrefix : seq<exponentPrefix, exponent> {};
template <SIM_VALUE_BASE::TYPE ValueType, NOTATION Notation>
template <SIM_VALUE::TYPE ValueType, NOTATION Notation>
struct metricSuffix;
template <> struct metricSuffix<SIM_VALUE_BASE::TYPE::INT, NOTATION::SI>
template <> struct metricSuffix<SIM_VALUE::TYPE::INT, NOTATION::SI>
: one<'k', 'K', 'M', 'G', 'T', 'P', 'E'> {};
template <> struct metricSuffix<SIM_VALUE_BASE::TYPE::INT, NOTATION::SPICE>
template <> struct metricSuffix<SIM_VALUE::TYPE::INT, NOTATION::SPICE>
: sor<TAO_PEGTL_ISTRING( "k" ),
TAO_PEGTL_ISTRING( "Meg" ),
TAO_PEGTL_ISTRING( "G" ),
TAO_PEGTL_ISTRING( "T" )> {};
template <> struct metricSuffix<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SI>
template <> struct metricSuffix<SIM_VALUE::TYPE::FLOAT, NOTATION::SI>
: one<'a', 'f', 'p', 'n', 'u', 'm', 'k', 'K', 'M', 'G', 'T', 'P', 'E'> {};
template <> struct metricSuffix<SIM_VALUE_BASE::TYPE::FLOAT, NOTATION::SPICE>
template <> struct metricSuffix<SIM_VALUE::TYPE::FLOAT, NOTATION::SPICE>
: sor<TAO_PEGTL_ISTRING( "f" ),
TAO_PEGTL_ISTRING( "p" ),
TAO_PEGTL_ISTRING( "n" ),
@ -155,17 +162,17 @@ namespace SIM_VALUE_GRAMMAR
TAO_PEGTL_ISTRING( "T" )> {};
template <SIM_VALUE_BASE::TYPE ValueType, NOTATION Notation>
template <SIM_VALUE::TYPE ValueType, NOTATION Notation>
struct number : seq<significand<ValueType>,
opt<exponentWithPrefix>,
opt<metricSuffix<ValueType, Notation>>> {};
template <SIM_VALUE_BASE::TYPE ValueType, NOTATION Notation>
template <SIM_VALUE::TYPE ValueType, NOTATION Notation>
struct numberGrammar : must<opt<number<ValueType, Notation>>, eof> {};
bool IsValid( const wxString& aString,
SIM_VALUE_BASE::TYPE aValueType = SIM_VALUE_BASE::TYPE::FLOAT,
SIM_VALUE::TYPE aValueType = SIM_VALUE::TYPE::FLOAT,
NOTATION aNotation = NOTATION::SI );
}

View File

@ -72,9 +72,9 @@ bool SIM_WORKBOOK::DeletePage( size_t page )
bool SIM_WORKBOOK::AddTrace( SIM_PLOT_PANEL* aPlotPanel, const wxString& aTitle,
const wxString& aName, int aPoints, const double* aX, const double* aY,
SIM_PLOT_TYPE aType, const wxString& aParam )
SIM_PLOT_TYPE aType )
{
bool res = aPlotPanel->addTrace( aTitle, aName, aPoints, aX, aY, aType, aParam );
bool res = aPlotPanel->addTrace( aTitle, aName, aPoints, aX, aY, aType );
setModified( res );
return res;
}

View File

@ -49,8 +49,7 @@ public:
// Custom methods
bool AddTrace( SIM_PLOT_PANEL* aPlotPanel, const wxString& aTitle, const wxString& aName,
int aPoints, const double* aX, const double* aY, SIM_PLOT_TYPE aType,
const wxString& aParam );
int aPoints, const double* aX, const double* aY, SIM_PLOT_TYPE aType );
bool DeleteTrace( SIM_PLOT_PANEL* aPlotPanel, const wxString& aName );
void SetSimCommand( SIM_PANEL_BASE* aPlotPanel, const wxString& aSimCommand )

View File

@ -55,30 +55,27 @@ namespace SPICE_GRAMMAR
struct param : plus<alnum> {};
struct suffixUnit : plus<alpha> {};
template <SIM_VALUE_BASE::TYPE Type, NOTATION Notation>
template <SIM_VALUE::TYPE Type, NOTATION Notation>
struct paramValuePair : seq<param,
opt<sep>,
one<'='>,
opt<sep>,
number<Type, Notation>> {};
number<Type, Notation>,
opt<suffixUnit>> {};
template <NOTATION Notation>
struct paramValuePairs : seq<opt<paramValuePair<SIM_VALUE_BASE::TYPE::FLOAT,
struct paramValuePairs : seq<opt<paramValuePair<SIM_VALUE::TYPE::FLOAT,
Notation>,
star<sep,
paramValuePair<SIM_VALUE_BASE::TYPE::FLOAT,
paramValuePair<SIM_VALUE::TYPE::FLOAT,
Notation>>>> {};
struct modelName : plus<alnum,
star<sor<alnum,
one<'!', '#', '$', '%', '[', ']', '_'>>>> {};
/*seq<alpha,
star<sor<alnum,
one<'!', '#', '$', '%', '[', ']', '_'>>>> {};*/
struct dotModelType : sor<TAO_PEGTL_ISTRING( "R" ),
TAO_PEGTL_ISTRING( "C" ),
TAO_PEGTL_ISTRING( "L" ),
@ -96,7 +93,6 @@ namespace SPICE_GRAMMAR
TAO_PEGTL_ISTRING( "NMF" ),
TAO_PEGTL_ISTRING( "PMF" ),
TAO_PEGTL_ISTRING( "VDMOS" )> {};
struct dotModel : seq<opt<sep>,
TAO_PEGTL_ISTRING( ".model" ),
sep,
@ -116,41 +112,76 @@ namespace SPICE_GRAMMAR
newline> {};
struct dotSubcktPinNumber : digits {};
struct dotSubcktPinSequence : seq<opt<sep>,
opt<dotSubcktPinNumber,
struct dotSubcktPinName : seq<not_at<TAO_PEGTL_ISTRING( "params:" )>,
plus<not_at<space>,
any>> {};
struct dotSubcktPinSequence : seq<opt<dotSubcktPinName,
star<sep,
dotSubcktPinNumber>>,
opt<sep>> {};
dotSubcktPinName>>> {};
struct dotSubcktEnd : seq<TAO_PEGTL_ISTRING( ".ends" ),
opt<sep>,
newline> {};
struct dotSubckt : seq<opt<sep>,
TAO_PEGTL_ISTRING( ".subckt" ),
sep,
modelName,
sep,
dotSubcktPinSequence,
opt<sep,
TAO_PEGTL_ISTRING( "params:" ),
sep,
paramValuePairs<NOTATION::SPICE>>,
opt<sep>,
newline,
until<dotSubcktEnd>> {};
struct modelUnit : sor<dotModel,
dotSubckt> {};
struct dotTitleTitle : star<not_at<newline>, any> {};
struct dotTitle : seq<opt<sep>,
TAO_PEGTL_ISTRING( ".title" ),
sep,
dotTitleTitle,
newline> {};
struct dotIncludePathWithoutQuotes : star<not_one<'"'>> {};
struct dotIncludePathWithoutApostrophes : star<not_one<'\''>> {};
struct dotIncludePath : star<not_at<newline>, any> {};
struct dotInclude : seq<opt<sep>,
TAO_PEGTL_ISTRING( ".include" ),
sep,
sor<seq<one<'\"'>,
dotIncludePathWithoutQuotes,
one<'\"'>>,
seq<one<'\''>,
dotIncludePathWithoutApostrophes,
one<'\''>>,
dotIncludePath>,
opt<sep>,
newline> {};
struct dotLine : seq<opt<sep>,
one<'.'>,
until<newline>> {};
struct unknownLine : until<newline> {};
struct spiceUnit : sor<modelUnit,
dotTitle,
dotInclude,
dotLine,
unknownLine> {};
struct spiceUnitGrammar : must<spiceUnit, eof> {};
struct spiceSource : star<spiceUnit> {};
struct spiceSourceGrammar : must<spiceSource, eof> {};
}
#endif // SPICE_GRAMMAR_H

View File

@ -36,7 +36,7 @@
#include <string_utils.h>
#include <kiway.h>
#include <kiway_player.h>
#include <netlist_exporters/netlist_exporter_pspice.h>
#include <netlist_exporters/netlist_exporter_spice.h>
#include <project/project_file.h>
#include <project/net_settings.h>
#include <sch_edit_frame.h>
@ -61,6 +61,7 @@
#include <drawing_sheet/ds_proxy_undo_item.h>
#include <dialog_update_from_pcb.h>
#include <eda_list_dialog.h>
#include <locale_io.h>
#include <wildcards_and_files_ext.h>
#include <sch_sheet_path.h>
@ -741,6 +742,7 @@ static KICAD_T fieldsAndSymbols[] = { SCH_SYMBOL_T, SCH_FIELD_T, EOT };
int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
{
LOCALE_IO toggle;
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
SIM_PLOT_FRAME* simFrame = (SIM_PLOT_FRAME*) m_frame->Kiway().Player( FRAME_SIMULATOR, false );
@ -765,30 +767,76 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
if( !item )
return false;
if( item->IsType( wires ) )
if( item->Type() == SCH_PIN_T )
{
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
std::vector<SCH_PIN*> pins = symbol->GetAllPins();
int symbolPinNumber = static_cast<int>( std::distance( pins.begin(),
std::find( pins.begin(), pins.end(), pin ) ) ) + 1;
// TODO: We need to unify this library-model inheritance stuff into one
// abstraction.
// It might not be the best idea to have to load a file every time current is
// probed either.
std::unique_ptr<SIM_MODEL> model;
std::unique_ptr<SIM_LIBRARY> library;
SCH_FIELD* libraryField = symbol->FindField( SIM_LIBRARY::LIBRARY_FIELD );
SCH_FIELD* nameField = symbol->FindField( SIM_LIBRARY::NAME_FIELD );
if( libraryField )
{
wxString path = m_frame->Prj().AbsolutePath( libraryField->GetShownText() );
library = SIM_LIBRARY::Create( path );
if( !library || !nameField )
return true;
SIM_MODEL* baseModel = library->FindModel( nameField->GetShownText() );
if( !baseModel )
return true;
model = SIM_MODEL::Create( *baseModel,
static_cast<int>( pins.size() ),
symbol->GetFields() );
}
else
model = SIM_MODEL::Create( static_cast<int>( pins.size() ),
symbol->GetFields() );
wxString ref = symbol->GetRef( &m_frame->GetCurrentSheet() );
std::vector<wxString> currentNames = model->GenerateSpiceCurrentNames( ref );
if( currentNames.size() == 0 )
return true;
else if( currentNames.size() == 1 )
{
simFrame->AddCurrentPlot( currentNames.at( 0 ) );
return true;
}
int modelPinNumber = model->FindModelPinNumber( symbolPinNumber );
if( modelPinNumber > 0 )
{
wxString name = currentNames.at( modelPinNumber - 1 );
simFrame->AddCurrentPlot( name );
}
}
else if( item->IsType( wires ) )
{
if( SCH_CONNECTION* conn = static_cast<SCH_ITEM*>( item )->Connection() )
simFrame->AddVoltagePlot( UnescapeString( conn->Name() ) );
}
else if( item->Type() == SCH_PIN_T )
{
SCH_PIN* pin = (SCH_PIN*) item;
SCH_SYMBOL* symbol = (SCH_SYMBOL*) item->GetParent();
wxString ref = symbol->GetRef( &m_frame->GetCurrentSheet() );
wxString param;
wxString primitive;
{
wxString spiceNet = UnescapeString( conn->Name() );
NETLIST_EXPORTER_SPICE::ReplaceForbiddenChars( spiceNet );
primitive = NETLIST_EXPORTER_PSPICE::GetSpiceField( SF_PRIMITIVE, symbol, 0 );
primitive.LowerCase();
if( primitive == "c" || primitive == "l" || primitive == "r" )
param = wxT( "I" );
else if( primitive == "d" )
param = wxT( "Id" );
else
param = wxString::Format( wxT( "I%s" ), pin->GetShownName().Lower() );
simFrame->AddCurrentPlot( ref, param );
simFrame->AddVoltagePlot( wxString::Format( "V(%s)", spiceNet ) );
}
}
return true;

View File

@ -189,7 +189,9 @@ TUNER_SLIDER::TUNER_SLIDER( SIM_PLOT_FRAME* aFrame, wxWindow* aParent, SCH_SYMBO
m_changed( false ),
m_frame ( aFrame )
{
const wxString compName = aSymbol->GetField( REFERENCE_FIELD )->GetText();
// TODO.
/*const wxString compName = aSymbol->GetField( REFERENCE_FIELD )->GetText();
m_name->SetLabel( compName );
m_spiceTuningCommand = aFrame->GetExporter()->GetSpiceTuningCommand( compName );
@ -206,8 +208,8 @@ TUNER_SLIDER::TUNER_SLIDER( SIM_PLOT_FRAME* aFrame, wxWindow* aParent, SCH_SYMBO
else
{
// instance parameter
if( aSymbol->FindField( NETLIST_EXPORTER_PSPICE::GetSpiceFieldName( SF_MODEL ) ) )
m_fieldId = aSymbol->FindField( NETLIST_EXPORTER_PSPICE::GetSpiceFieldName( SF_MODEL ) )->GetId();
if( aSymbol->FindField( netlist_exporter_spice::GetSpiceFieldName( SF_MODEL ) ) )
m_fieldId = aSymbol->FindField( netlist_exporter_spice::GetSpiceFieldName( SF_MODEL ) )->GetId();
else
m_fieldId = aSymbol->GetField( VALUE_FIELD )->GetId();
@ -224,7 +226,7 @@ TUNER_SLIDER::TUNER_SLIDER( SIM_PLOT_FRAME* aFrame, wxWindow* aParent, SCH_SYMBO
updateSlider();
m_simTimer.SetOwner( this );
Connect( wxEVT_TIMER, wxTimerEventHandler( TUNER_SLIDER::onSimTimer ), nullptr, this );
Connect( wxEVT_TIMER, wxTimerEventHandler( TUNER_SLIDER::onSimTimer ), nullptr, this );*/
}

View File

@ -0,0 +1,9 @@
.title KiCad schematic
.include "chirp.lib"
.save all
.probe alli
.tran 10u 100m
XV1 Net-_V1-E1_ Net-_V1-E2_ chirp bf=1k ef=3k bt=30m et=70m
R1 Net-_V1-E1_ Net-_V1-E2_ 10k
.end

View File

@ -0,0 +1,2 @@
(kicad_pcb (version 20220308) (generator pcbnew)
)

View File

@ -0,0 +1,331 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.1,
"copper_line_width": 0.2,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"other_line_width": 0.15,
"silk_line_width": 0.15,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"rules": {
"min_copper_edge_clearance": 0.0,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0
},
"track_widths": [],
"via_dimensions": []
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "chirp.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Spice",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"spice_save_all_currents": true,
"spice_save_all_voltages": true,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"eb2ce6e2-4c97-4068-82f1-b3ad4f047462",
""
]
],
"text_variables": {}
}

View File

@ -0,0 +1,193 @@
(kicad_sch (version 20220331) (generator eeschema)
(uuid eb2ce6e2-4c97-4068-82f1-b3ad4f047462)
(paper "A4")
(lib_symbols
(symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes)
(property "Reference" "R" (id 0) (at 2.032 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "R" (id 1) (at 0 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at -1.778 0 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "R res resistor" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Resistor" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "R_*" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "R_0_1"
(rectangle (start -1.016 -2.54) (end 1.016 2.54)
(stroke (width 0.254) (type default))
(fill (type none))
)
)
(symbol "R_1_1"
(pin passive line (at 0 3.81 270) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -3.81 90) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "pspice:VSOURCE" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "V" (id 0) (at -6.35 7.62 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "VSOURCE" (id 1) (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "simulation" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Voltage source symbol for simulation only" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "VSOURCE_0_1"
(polyline
(pts
(xy -6.35 -6.35)
(xy -6.35 3.81)
)
(stroke (width 0) (type default))
(fill (type outline))
)
(polyline
(pts
(xy -7.62 3.81)
(xy -6.35 6.35)
(xy -5.08 3.81)
)
(stroke (width 0) (type default))
(fill (type outline))
)
(circle (center 0 0) (radius 5.08)
(stroke (width 0) (type default))
(fill (type none))
)
(text "V" (at -8.128 -0.254 0)
(effects (font (size 1.27 1.27)))
)
)
(symbol "VSOURCE_1_1"
(pin input line (at 0 7.62 270) (length 2.54)
(name "E1" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin input line (at 0 -7.62 90) (length 2.54)
(name "E2" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
)
(wire (pts (xy 182.88 107.315) (xy 182.88 111.125))
(stroke (width 0) (type default))
(uuid 3c643958-d112-4743-bed0-8d4c351efeca)
)
(wire (pts (xy 160.655 122.555) (xy 182.88 122.555))
(stroke (width 0) (type default))
(uuid 6db20978-f158-409d-9385-faa8f9fe7ead)
)
(wire (pts (xy 160.655 107.315) (xy 182.88 107.315))
(stroke (width 0) (type default))
(uuid acb257ff-7594-49b9-9b47-4538b18772b4)
)
(wire (pts (xy 182.88 122.555) (xy 182.88 118.745))
(stroke (width 0) (type default))
(uuid ec6dd29a-008b-4f48-a33d-2f2833709a39)
)
(text ".tran 10u 100m" (at 160.655 103.505 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid 49e11e6d-285a-4b97-85e2-04ad8798efbd)
)
(symbol (lib_id "pspice:VSOURCE") (at 160.655 114.935 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid b47ba90e-d24f-47fa-967d-97f9b9ef4e05)
(property "Reference" "V1" (id 0) (at 166.37 114.3 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VSOURCE" (id 1) (at 166.37 116.84 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 160.655 114.935 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 160.655 114.935 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Name" "chirp" (id 4) (at 160.655 114.935 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Library" "chirp.lib" (id 5) (at 160.655 114.935 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "SUBCKT" (id 6) (at 160.655 114.935 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Params" "bf=1k ef=3k bt=30m et=70m" (id 7) (at 160.655 114.935 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "1 2" (id 8) (at 160.655 114.935 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 69509f58-8756-4cec-83fa-cd042c171c7a))
(pin "2" (uuid ef1a7634-c4c3-4c75-a241-106a391dae71))
)
(symbol (lib_id "Device:R") (at 182.88 114.935 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid f7b25816-e4a8-4219-9402-57c23b1eba25)
(property "Reference" "R1" (id 0) (at 185.42 114.3 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "10k" (id 1) (at 185.42 116.84 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 181.102 114.935 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 182.88 114.935 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 18fc09e3-d2b3-42f5-a1b2-442e588408fb))
(pin "2" (uuid 86bfef10-d24c-4c3d-9b54-1a55a3654ef8))
)
(sheet_instances
(path "/" (page "1"))
)
(symbol_instances
(path "/f7b25816-e4a8-4219-9402-57c23b1eba25"
(reference "R1") (unit 1) (value "10k") (footprint "")
)
(path "/b47ba90e-d24f-47fa-967d-97f9b9ef4e05"
(reference "V1") (unit 1) (value "VSOURCE") (footprint "")
)
)
)

View File

@ -0,0 +1,19 @@
* chirp generator by Holger Vogt
* public domain
* bt start time, et end time of chirp
* bf start frequency, ef end frequency of chirp
* code model 'sine' will not accept control value 0, so 1e-12 is used
* r=0 will lead to repeated chirp pattern, cannot be parameterized, so
* has to be removed if a single shot only is required
* to be called by 'XChirp pp 0 chirp bf=1k ef=10k bt=80m et=120m'
.subckt chirp p m params: bf=200 ef=2k bt=30m et=100m
* Start at t=0 with 1e-12, ramp up to t=et-bt with output et, ramp down
* to 1e-12 after another 5% of ramp up time (to catch output 0 again).
* Delay the whole pattern by bt
vcont cc 0 dc 1e-12 pwl ( 0 1e-12 {et - bt} {et} {(et - bt) * 1.05} 1e-12 td={bt} r=0 )
* amplitude is set by out_low, out_high
asine cc %vd(p m) in_sine
.model in_sine sine(cntl_array = [ 0 {bt} {et} ]
+ freq_array=[ 0 {bf} {ef} ] out_low = -5.0
+ out_high = 5.0)
.ends

View File

@ -0,0 +1 @@
.model NPN NPN()

View File

@ -0,0 +1,17 @@
.title KiCad schematic
.include "npn.lib"
.save all
.probe alli
.tran 1u 1m
R1 Net-_R1-Pad1_ Net-_Q1-B_ 1k
R2 Net-_Q1-B_ GND 1k
Q1 /out Net-_Q1-B_ Net-_Q1-E_ NPN
R4 Net-_Q1-E_ Net-_C2-Pad2_ 100
C2 Net-_Q1-E_ Net-_C2-Pad2_ 10u
R5 Net-_C2-Pad2_ GND 1
R3 Net-_R1-Pad1_ /out 100
V2 Net-_C1-Pad1_ GND SIN( 0 10m 10k )
C1 Net-_C1-Pad1_ Net-_Q1-B_ 10u
V1 Net-_R1-Pad1_ GND ( 9 )
.end

View File

@ -0,0 +1,2 @@
(kicad_pcb (version 20220308) (generator pcbnew)
)

View File

@ -0,0 +1,331 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.1,
"copper_line_width": 0.2,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"other_line_width": 0.15,
"silk_line_width": 0.15,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"rules": {
"min_copper_edge_clearance": 0.0,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0
},
"track_widths": [],
"via_dimensions": []
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "npn_ce_amp.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Spice",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"spice_save_all_currents": true,
"spice_save_all_voltages": true,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"48817d43-3f4d-4e7e-ae5d-40c9da0e33d5",
""
]
],
"text_variables": {}
}

View File

@ -0,0 +1,784 @@
(kicad_sch (version 20220331) (generator eeschema)
(uuid 48817d43-3f4d-4e7e-ae5d-40c9da0e33d5)
(paper "A4")
(lib_symbols
(symbol "Device:C" (pin_numbers hide) (pin_names (offset 0.254)) (in_bom yes) (on_board yes)
(property "Reference" "C" (id 0) (at 0.635 2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "C" (id 1) (at 0.635 -2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0.9652 -3.81 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "cap capacitor" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Unpolarized capacitor" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "C_*" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "C_0_1"
(polyline
(pts
(xy -2.032 -0.762)
(xy 2.032 -0.762)
)
(stroke (width 0.508) (type default))
(fill (type none))
)
(polyline
(pts
(xy -2.032 0.762)
(xy 2.032 0.762)
)
(stroke (width 0.508) (type default))
(fill (type none))
)
)
(symbol "C_1_1"
(pin passive line (at 0 3.81 270) (length 2.794)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -3.81 90) (length 2.794)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes)
(property "Reference" "R" (id 0) (at 2.032 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "R" (id 1) (at 0 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at -1.778 0 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "R res resistor" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Resistor" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "R_*" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "R_0_1"
(rectangle (start -1.016 -2.54) (end 1.016 2.54)
(stroke (width 0.254) (type default))
(fill (type none))
)
)
(symbol "R_1_1"
(pin passive line (at 0 3.81 270) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -3.81 90) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Simulation_SPICE:VDC" (pin_numbers hide) (pin_names (offset 0.0254)) (in_bom yes) (on_board yes)
(property "Reference" "V" (id 0) (at 2.54 2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VDC" (id 1) (at 2.54 0 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Spice_Netlist_Enabled" "Y" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Primitive" "V" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Model" "dc(1)" (id 6) (at 2.54 -2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "ki_keywords" "simulation" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Voltage source, DC" (id 8) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "VDC_0_0"
(polyline
(pts
(xy -1.27 0.254)
(xy 1.27 0.254)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.762 -0.254)
(xy -1.27 -0.254)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy 0.254 -0.254)
(xy -0.254 -0.254)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy 1.27 -0.254)
(xy 0.762 -0.254)
)
(stroke (width 0) (type default))
(fill (type none))
)
(text "+" (at 0 1.905 0)
(effects (font (size 1.27 1.27)))
)
)
(symbol "VDC_0_1"
(circle (center 0 0) (radius 2.54)
(stroke (width 0.254) (type default))
(fill (type background))
)
)
(symbol "VDC_1_1"
(pin passive line (at 0 5.08 270) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -5.08 90) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Simulation_SPICE:VSIN" (pin_numbers hide) (pin_names (offset 0.0254)) (in_bom yes) (on_board yes)
(property "Reference" "V" (id 0) (at 2.54 2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VSIN" (id 1) (at 2.54 0 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Spice_Netlist_Enabled" "Y" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Primitive" "V" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Model" "sin(0 1 1k)" (id 6) (at 2.54 -2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "ki_keywords" "simulation" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Voltage source, sinusoidal" (id 8) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "VSIN_0_0"
(arc (start 0 0) (mid -0.635 0.635) (end -1.27 0)
(stroke (width 0) (type default))
(fill (type none))
)
(arc (start 0 0) (mid 0.635 -0.635) (end 1.27 0)
(stroke (width 0) (type default))
(fill (type none))
)
(text "+" (at 0 1.905 0)
(effects (font (size 1.27 1.27)))
)
)
(symbol "VSIN_0_1"
(circle (center 0 0) (radius 2.54)
(stroke (width 0.254) (type default))
(fill (type background))
)
)
(symbol "VSIN_1_1"
(pin passive line (at 0 5.08 270) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -5.08 90) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "power:GND" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes)
(property "Reference" "#PWR" (id 0) (at 0 -6.35 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 0 -3.81 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "power-flag" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Power symbol creates a global label with name \"GND\" , ground" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "GND_0_1"
(polyline
(pts
(xy 0 0)
(xy 0 -1.27)
(xy 1.27 -1.27)
(xy 0 -2.54)
(xy -1.27 -1.27)
(xy 0 -1.27)
)
(stroke (width 0) (type default))
(fill (type none))
)
)
(symbol "GND_1_1"
(pin power_in line (at 0 0 270) (length 0) hide
(name "GND" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "pspice:QNPN" (pin_names (offset 0)) (in_bom yes) (on_board yes)
(property "Reference" "Q" (id 0) (at -2.54 7.62 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "QNPN" (id 1) (at -2.54 5.08 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "simulation" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Bipolar transistor symbol for simulation only" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "QNPN_0_0"
(polyline
(pts
(xy 0 0)
(xy 3.81 -3.81)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy 3.81 -3.81)
(xy 3.81 -1.27)
(xy 1.27 -3.81)
(xy 3.81 -3.81)
)
(stroke (width 0) (type default))
(fill (type outline))
)
)
(symbol "QNPN_0_1"
(polyline
(pts
(xy 0 -3.81)
(xy 0 3.81)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy 0 0)
(xy 3.81 3.81)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy -2.54 -3.81)
(xy 0 -3.81)
(xy 0 -3.81)
(xy 0 -3.81)
)
(stroke (width 0) (type default))
(fill (type none))
)
)
(symbol "QNPN_1_1"
(pin passive line (at 3.81 8.89 270) (length 5.08)
(name "C" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin input line (at -7.62 0 0) (length 7.62)
(name "B" (effects (font (size 1.016 1.016))))
(number "2" (effects (font (size 1.016 1.016))))
)
(pin passive line (at 3.81 -8.89 90) (length 5.08)
(name "E" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
(pin input line (at -2.54 -8.89 90) (length 5.08)
(name "Substrat" (effects (font (size 0.508 0.508))))
(number "4" (effects (font (size 1.27 1.27))))
)
)
)
)
(junction (at 127 88.9) (diameter 0) (color 0 0 0 0)
(uuid 2eb27429-99c6-43f1-ab3a-e07f043f82f5)
)
(junction (at 139.7 97.79) (diameter 0) (color 0 0 0 0)
(uuid 4e188539-9ab7-497e-84d4-c3bee17b027b)
)
(junction (at 139.7 80.01) (diameter 0) (color 0 0 0 0)
(uuid ce5e9abd-d4b7-4b58-a707-251c589c5b19)
)
(junction (at 127 80.01) (diameter 0) (color 0 0 0 0)
(uuid f5815d32-c7dd-4b6d-8947-1b811877f44b)
)
(junction (at 139.7 105.41) (diameter 0) (color 0 0 0 0)
(uuid f84a27e7-86c2-401c-9459-b27c006b315b)
)
(wire (pts (xy 114.3 88.9) (xy 116.84 88.9))
(stroke (width 0) (type default))
(uuid 39ba2b9a-f0eb-4826-ade9-2086689ddc8a)
)
(wire (pts (xy 124.46 88.9) (xy 127 88.9))
(stroke (width 0) (type default))
(uuid 56337226-41a7-4ad0-9ecf-a730d560ee37)
)
(wire (pts (xy 139.7 80.01) (xy 152.4 80.01))
(stroke (width 0) (type default))
(uuid 64d3e839-c616-44e5-b743-98f771a45d22)
)
(wire (pts (xy 127 88.9) (xy 128.27 88.9))
(stroke (width 0) (type default))
(uuid 98d1b729-095f-4956-8e41-4cf365e5a8d7)
)
(wire (pts (xy 101.6 80.01) (xy 127 80.01))
(stroke (width 0) (type default))
(uuid a2a84ef7-d640-4078-ad6a-d7bd7b00341e)
)
(wire (pts (xy 127 72.39) (xy 139.7 72.39))
(stroke (width 0) (type default))
(uuid b31edc00-e7c5-48ef-8d13-d54576130799)
)
(wire (pts (xy 139.7 97.79) (xy 148.59 97.79))
(stroke (width 0) (type default))
(uuid c8375630-61ad-453c-bb9d-bb40b7718489)
)
(wire (pts (xy 127 80.01) (xy 127 72.39))
(stroke (width 0) (type default))
(uuid d60be661-d07d-4126-90bd-1aee65c8a312)
)
(wire (pts (xy 139.7 105.41) (xy 148.59 105.41))
(stroke (width 0) (type default))
(uuid f540870a-1f9f-4479-b851-0fba475c7998)
)
(wire (pts (xy 127 80.01) (xy 127 81.28))
(stroke (width 0) (type default))
(uuid f8fb058f-04c4-496b-bb49-df66dbf14c64)
)
(text ".tran 1u 1m" (at 127 69.215 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid d9f81d0b-eee9-4ffb-83bb-dfeab4cb8e24)
)
(label "out" (at 152.4 80.01 0) (fields_autoplaced)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid 8829145d-f83c-4c92-bedf-89385f7a7a60)
)
(symbol (lib_id "power:GND") (at 114.3 99.06 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 061346ed-4da6-4a14-a5e0-8de9493b719a)
(property "Reference" "#PWR02" (id 0) (at 114.3 105.41 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 114.3 104.14 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 114.3 99.06 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 114.3 99.06 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 83f723ea-ff2d-48b4-8ec3-74cc96ebe999))
)
(symbol (lib_id "power:GND") (at 101.6 90.17 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 08f4cc24-6109-4be7-97a5-71df29b2d29f)
(property "Reference" "#PWR01" (id 0) (at 101.6 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 101.6 95.25 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 101.6 90.17 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 101.6 90.17 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 88b21522-3f3c-4db4-9769-ae14b29b6781))
)
(symbol (lib_id "Device:C") (at 120.65 88.9 90) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 109ed64a-f514-4270-a826-da4127b6e73a)
(property "Reference" "C1" (id 0) (at 120.65 83.185 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "10u" (id 1) (at 120.65 85.725 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 124.46 87.9348 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 120.65 88.9 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 94852f4d-516a-49ae-94b0-d7194707acba))
(pin "2" (uuid 8245b736-a715-43fb-a993-1e7d8dd85088))
)
(symbol (lib_id "power:GND") (at 127 96.52 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 17af0f63-5021-4f46-8172-d3543add2835)
(property "Reference" "#PWR03" (id 0) (at 127 102.87 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 127 101.6 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 127 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 127 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 65737eca-fffa-449e-aafc-2e967da04521))
)
(symbol (lib_id "pspice:QNPN") (at 135.89 88.9 0) (unit 1)
(in_bom yes) (on_board yes)
(uuid 3f259f4e-365c-40fc-8137-1466a8c5c7ef)
(property "Reference" "Q1" (id 0) (at 140.97 88.265 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "QNPN" (id 1) (at 140.97 90.805 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 135.89 88.9 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 135.89 88.9 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Name" "NPN" (id 4) (at 142.875 92.71 0)
(effects (font (size 1.27 1.27)))
)
(property "Model_Library" "npn.lib" (id 5) (at 135.89 88.9 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "NPN" (id 6) (at 135.89 88.9 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Type" "GUMMELPOON" (id 7) (at 135.89 88.9 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "1 2 3" (id 8) (at 135.89 88.9 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid d3ec8923-753b-4949-adc8-2a01d4bd537e))
(pin "2" (uuid 42795dbf-587b-4da5-aefc-85a3f25a77df))
(pin "3" (uuid 25abd39f-a15b-4113-b403-09c28f4681f1))
(pin "4" (uuid 621fb5ea-5b78-4f68-aa28-035eca0a9dd8))
)
(symbol (lib_id "Device:C") (at 148.59 101.6 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 421b287f-c4c7-4e68-ba3e-8378150e3ed3)
(property "Reference" "C2" (id 0) (at 152.4 100.965 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "10u" (id 1) (at 152.4 103.505 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 149.5552 105.41 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 148.59 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid e537f30b-df49-4540-b7c3-be90d17f9974))
(pin "2" (uuid b5484ad9-186a-4b7a-98c3-a367c224e24d))
)
(symbol (lib_id "Device:R") (at 139.7 76.2 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 828bdd14-2bce-4c2a-bef8-32e29077432d)
(property "Reference" "R3" (id 0) (at 142.24 75.565 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "100" (id 1) (at 142.24 78.105 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 137.922 76.2 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 139.7 76.2 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid e6274a8f-746c-4ba0-8504-4c8082be16cf))
(pin "2" (uuid 2f15bad6-8ea3-4281-8207-ccd6f867f80a))
)
(symbol (lib_id "Simulation_SPICE:VSIN") (at 114.3 93.98 0) (unit 1)
(in_bom yes) (on_board yes)
(uuid 973698df-46a0-4ee0-8e2f-010cef494e09)
(property "Reference" "V2" (id 0) (at 118.11 92.075 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VSIN" (id 1) (at 118.11 94.615 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 114.3 93.98 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 114.3 93.98 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "V" (id 4) (at 114.3 93.98 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Type" "SIN" (id 5) (at 114.3 93.98 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "1 2" (id 6) (at 114.3 93.98 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Params" "dc=0 ampl=10m f=10k" (id 7) (at 114.3 106.68 0)
(effects (font (size 1.27 1.27)))
)
(pin "1" (uuid 0a7ec182-cf4b-4daf-b269-fcaedb3df0f3))
(pin "2" (uuid 596254af-bf1c-427b-b9a4-c13b03eb4ff4))
)
(symbol (lib_id "Device:R") (at 139.7 101.6 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 9abffa5d-8f8e-48ca-9c33-a1eed76e9781)
(property "Reference" "R4" (id 0) (at 142.24 100.965 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "100" (id 1) (at 142.24 103.505 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 137.922 101.6 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 139.7 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 537b0f91-9fdd-4f38-a125-8bcc16fcae66))
(pin "2" (uuid 5a32069d-e4f7-494e-a9f9-417b71f15917))
)
(symbol (lib_id "power:GND") (at 139.7 113.03 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 9d340c06-d2c1-4cea-a45c-57ace419a42d)
(property "Reference" "#PWR04" (id 0) (at 139.7 119.38 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 139.7 118.11 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 139.7 113.03 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 139.7 113.03 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid f18d6b69-bb80-4308-b580-63a17dfe3cb3))
)
(symbol (lib_id "Device:R") (at 127 85.09 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid ba613c64-0be9-4501-b395-e3e38eac86ff)
(property "Reference" "R1" (id 0) (at 129.54 84.455 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "1K" (id 1) (at 129.54 86.995 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 125.222 85.09 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 127 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 4bd7b8c1-ef81-4d9e-8786-74309346686c))
(pin "2" (uuid 8deb3938-9d5d-4eb6-9d1a-d76714cf7d00))
)
(symbol (lib_id "Device:R") (at 139.7 109.22 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid c22aa62c-3c8e-4552-b484-d91273a5b61e)
(property "Reference" "R5" (id 0) (at 142.24 108.585 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "1" (id 1) (at 142.24 111.125 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 137.922 109.22 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 139.7 109.22 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 4bb143a1-985c-492c-a6e7-e81a25da1fda))
(pin "2" (uuid 6e8b12d9-2933-4936-8fd0-349ca0293a71))
)
(symbol (lib_id "Device:R") (at 127 92.71 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid ca47da07-3be8-494b-9bdc-6f05b2f70bc4)
(property "Reference" "R2" (id 0) (at 129.54 92.075 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "1K" (id 1) (at 129.54 94.615 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 125.222 92.71 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 127 92.71 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 305f44d5-f5cd-42d1-81ea-89b233f6b5a9))
(pin "2" (uuid 8dbdc783-b66f-430c-a6e5-5b06dc41f34a))
)
(symbol (lib_id "Simulation_SPICE:VDC") (at 101.6 85.09 0) (unit 1)
(in_bom yes) (on_board yes)
(uuid e1dfe550-04dd-4714-a41a-aa2825a2881f)
(property "Reference" "V1" (id 0) (at 105.41 83.185 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VDC" (id 1) (at 105.41 85.725 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 101.6 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 101.6 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "V" (id 4) (at 101.6 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Type" "DC" (id 5) (at 101.6 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "1 2" (id 6) (at 101.6 85.09 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Params" "dc=9" (id 7) (at 107.95 87.63 0)
(effects (font (size 1.27 1.27)))
)
(pin "1" (uuid 925c8d5e-6ef7-4cb4-8784-a2246cc254a4))
(pin "2" (uuid 96d96be8-6f6d-4018-b662-0935a67221b6))
)
(sheet_instances
(path "/" (page "1"))
)
(symbol_instances
(path "/08f4cc24-6109-4be7-97a5-71df29b2d29f"
(reference "#PWR01") (unit 1) (value "GND") (footprint "")
)
(path "/061346ed-4da6-4a14-a5e0-8de9493b719a"
(reference "#PWR02") (unit 1) (value "GND") (footprint "")
)
(path "/17af0f63-5021-4f46-8172-d3543add2835"
(reference "#PWR03") (unit 1) (value "GND") (footprint "")
)
(path "/9d340c06-d2c1-4cea-a45c-57ace419a42d"
(reference "#PWR04") (unit 1) (value "GND") (footprint "")
)
(path "/109ed64a-f514-4270-a826-da4127b6e73a"
(reference "C1") (unit 1) (value "10u") (footprint "")
)
(path "/421b287f-c4c7-4e68-ba3e-8378150e3ed3"
(reference "C2") (unit 1) (value "10u") (footprint "")
)
(path "/3f259f4e-365c-40fc-8137-1466a8c5c7ef"
(reference "Q1") (unit 1) (value "QNPN") (footprint "")
)
(path "/ba613c64-0be9-4501-b395-e3e38eac86ff"
(reference "R1") (unit 1) (value "1K") (footprint "")
)
(path "/ca47da07-3be8-494b-9bdc-6f05b2f70bc4"
(reference "R2") (unit 1) (value "1K") (footprint "")
)
(path "/828bdd14-2bce-4c2a-bef8-32e29077432d"
(reference "R3") (unit 1) (value "100") (footprint "")
)
(path "/9abffa5d-8f8e-48ca-9c33-a1eed76e9781"
(reference "R4") (unit 1) (value "100") (footprint "")
)
(path "/c22aa62c-3c8e-4552-b484-d91273a5b61e"
(reference "R5") (unit 1) (value "1") (footprint "")
)
(path "/e1dfe550-04dd-4714-a41a-aa2825a2881f"
(reference "V1") (unit 1) (value "VDC") (footprint "")
)
(path "/973698df-46a0-4ee0-8e2f-010cef494e09"
(reference "V2") (unit 1) (value "VSIN") (footprint "")
)
)
)

View File

@ -0,0 +1,13 @@
.title KiCad schematic
.include "opamp.lib"
.save all
.probe alli
.tran 10u 10m
V3 GND Net-_U1-V-_ ( 5 )
R2 Net-_U1--_ Net-_R2-Pad2_ 10k
XU1 Net-_U1-+_ Net-_U1--_ Net-_U1-V+_ Net-_U1-V-_ Net-_R2-Pad2_ uopamp_lvl2
V2 Net-_U1-V+_ GND ( 5 )
V1 Net-_U1-+_ GND SIN( 0 100m 1k )
R1 GND Net-_U1--_ 10k
.end

View File

@ -0,0 +1,2 @@
(kicad_pcb (version 20220308) (generator pcbnew)
)

View File

@ -0,0 +1,331 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.1,
"copper_line_width": 0.2,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"other_line_width": 0.15,
"silk_line_width": 0.15,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"rules": {
"min_copper_edge_clearance": 0.0,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0
},
"track_widths": [],
"via_dimensions": []
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "opamp.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Spice",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"spice_save_all_currents": true,
"spice_save_all_voltages": true,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"fd5567b0-04f0-4d9e-b647-1775367d8ff4",
""
]
],
"text_variables": {}
}

View File

@ -0,0 +1,596 @@
(kicad_sch (version 20220331) (generator eeschema)
(uuid fd5567b0-04f0-4d9e-b647-1775367d8ff4)
(paper "A4")
(lib_symbols
(symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes)
(property "Reference" "R" (id 0) (at 2.032 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "R" (id 1) (at 0 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at -1.778 0 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "R res resistor" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Resistor" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "R_*" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "R_0_1"
(rectangle (start -1.016 -2.54) (end 1.016 2.54)
(stroke (width 0.254) (type default))
(fill (type none))
)
)
(symbol "R_1_1"
(pin passive line (at 0 3.81 270) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -3.81 90) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Simulation_SPICE:OPAMP" (pin_names (offset 0.254)) (in_bom yes) (on_board yes)
(property "Reference" "U" (id 0) (at 3.81 3.175 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "OPAMP" (id 1) (at 3.81 -3.175 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Spice_Netlist_Enabled" "Y" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Primitive" "X" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "ki_keywords" "simulation" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Operational amplifier, single, node sequence=1:+ 2:- 3:OUT 4:V+ 5:V-" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "OPAMP_0_1"
(polyline
(pts
(xy 5.08 0)
(xy -5.08 5.08)
(xy -5.08 -5.08)
(xy 5.08 0)
)
(stroke (width 0.254) (type default))
(fill (type background))
)
)
(symbol "OPAMP_1_1"
(pin input line (at -7.62 2.54 0) (length 2.54)
(name "+" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin input line (at -7.62 -2.54 0) (length 2.54)
(name "-" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin output line (at 7.62 0 180) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
(pin power_in line (at -2.54 7.62 270) (length 3.81)
(name "V+" (effects (font (size 1.27 1.27))))
(number "4" (effects (font (size 1.27 1.27))))
)
(pin power_in line (at -2.54 -7.62 90) (length 3.81)
(name "V-" (effects (font (size 1.27 1.27))))
(number "5" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Simulation_SPICE:VDC" (pin_numbers hide) (pin_names (offset 0.0254)) (in_bom yes) (on_board yes)
(property "Reference" "V" (id 0) (at 2.54 2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VDC" (id 1) (at 2.54 0 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Spice_Netlist_Enabled" "Y" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Primitive" "V" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Model" "dc(1)" (id 6) (at 2.54 -2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "ki_keywords" "simulation" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Voltage source, DC" (id 8) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "VDC_0_0"
(polyline
(pts
(xy -1.27 0.254)
(xy 1.27 0.254)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy -0.762 -0.254)
(xy -1.27 -0.254)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy 0.254 -0.254)
(xy -0.254 -0.254)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy 1.27 -0.254)
(xy 0.762 -0.254)
)
(stroke (width 0) (type default))
(fill (type none))
)
(text "+" (at 0 1.905 0)
(effects (font (size 1.27 1.27)))
)
)
(symbol "VDC_0_1"
(circle (center 0 0) (radius 2.54)
(stroke (width 0.254) (type default))
(fill (type background))
)
)
(symbol "VDC_1_1"
(pin passive line (at 0 5.08 270) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -5.08 90) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Simulation_SPICE:VSIN" (pin_numbers hide) (pin_names (offset 0.0254)) (in_bom yes) (on_board yes)
(property "Reference" "V" (id 0) (at 2.54 2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VSIN" (id 1) (at 2.54 0 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Spice_Netlist_Enabled" "Y" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Primitive" "V" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Model" "sin(0 1 1k)" (id 6) (at 2.54 -2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "ki_keywords" "simulation" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Voltage source, sinusoidal" (id 8) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "VSIN_0_0"
(arc (start 0 0) (mid -0.635 0.635) (end -1.27 0)
(stroke (width 0) (type default))
(fill (type none))
)
(arc (start 0 0) (mid 0.635 -0.635) (end 1.27 0)
(stroke (width 0) (type default))
(fill (type none))
)
(text "+" (at 0 1.905 0)
(effects (font (size 1.27 1.27)))
)
)
(symbol "VSIN_0_1"
(circle (center 0 0) (radius 2.54)
(stroke (width 0.254) (type default))
(fill (type background))
)
)
(symbol "VSIN_1_1"
(pin passive line (at 0 5.08 270) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -5.08 90) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "power:GND" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes)
(property "Reference" "#PWR" (id 0) (at 0 -6.35 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 0 -3.81 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "power-flag" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Power symbol creates a global label with name \"GND\" , ground" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "GND_0_1"
(polyline
(pts
(xy 0 0)
(xy 0 -1.27)
(xy 1.27 -1.27)
(xy 0 -2.54)
(xy -1.27 -1.27)
(xy 0 -1.27)
)
(stroke (width 0) (type default))
(fill (type none))
)
)
(symbol "GND_1_1"
(pin power_in line (at 0 0 270) (length 0) hide
(name "GND" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
)
)
)
(junction (at 152.4 113.665) (diameter 0) (color 0 0 0 0)
(uuid 7d5f9c7f-c76d-40e1-8801-1df86d468cda)
)
(wire (pts (xy 142.24 88.9) (xy 152.4 88.9))
(stroke (width 0) (type default))
(uuid 21fe00e7-ba60-4b15-8ef1-025eba89442f)
)
(wire (pts (xy 168.91 91.44) (xy 168.91 113.665))
(stroke (width 0) (type default))
(uuid 2738cace-8583-4dd0-a73a-e0a00514d71c)
)
(wire (pts (xy 152.4 93.98) (xy 152.4 113.665))
(stroke (width 0) (type default))
(uuid 384ae57c-e54d-47a4-ba2d-a5f118361f7b)
)
(wire (pts (xy 168.91 113.665) (xy 160.02 113.665))
(stroke (width 0) (type default))
(uuid 464d44f8-2560-4ecf-89c9-500fb5853871)
)
(wire (pts (xy 142.24 91.44) (xy 142.24 88.9))
(stroke (width 0) (type default))
(uuid 494e3baa-08d1-4e6f-b155-e344680652a8)
)
(wire (pts (xy 167.64 91.44) (xy 168.91 91.44))
(stroke (width 0) (type default))
(uuid 55368b74-95a7-4cf2-8f86-415db816907d)
)
(text ".tran 10u 10m" (at 138.43 86.36 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid be48cb8e-7c9f-4216-838e-ee151aaeb3f9)
)
(symbol (lib_id "power:GND") (at 157.48 109.22 0) (unit 1)
(in_bom yes) (on_board yes)
(uuid 032a39b4-2686-4cc0-a834-fb52cf55377c)
(property "Reference" "#PWR04" (id 0) (at 157.48 115.57 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 161.29 111.125 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 157.48 109.22 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 157.48 109.22 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 233df94f-5b6f-4745-8784-1c2d9119d27f))
)
(symbol (lib_id "Simulation_SPICE:VSIN") (at 142.24 96.52 0) (unit 1)
(in_bom yes) (on_board yes)
(uuid 10f44001-5f65-44eb-a535-b7b3c67d5b83)
(property "Reference" "V1" (id 0) (at 146.05 94.615 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VSIN" (id 1) (at 146.05 97.155 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 142.24 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 142.24 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "V" (id 4) (at 142.24 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Type" "SIN" (id 5) (at 142.24 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "1 2" (id 6) (at 142.24 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Params" "dc=0 ampl=100m f=1k" (id 7) (at 129.54 92.71 0)
(effects (font (size 1.27 1.27)))
)
(pin "1" (uuid 27dbfa5d-bb20-468f-9a81-7737a5e908fc))
(pin "2" (uuid 63677ebb-93e3-49bb-8bf1-14fce6c8137d))
)
(symbol (lib_id "Device:R") (at 156.21 113.665 90) (unit 1)
(in_bom yes) (on_board yes)
(uuid 2a5b0448-42a8-4fa4-9a14-267dc34f9ff7)
(property "Reference" "R2" (id 0) (at 156.21 116.205 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "10K" (id 1) (at 156.21 118.745 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 156.21 115.443 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 156.21 113.665 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 7cf6d433-268b-4901-b74d-8803afdfc194))
(pin "2" (uuid 63068397-add3-45ea-b295-240f56e8c4f9))
)
(symbol (lib_id "Simulation_SPICE:VDC") (at 157.48 78.74 180) (unit 1)
(in_bom yes) (on_board yes)
(uuid 383ea298-1cb3-473e-8fce-19d3c7ac3912)
(property "Reference" "V2" (id 0) (at 161.29 76.835 0)
(effects (font (size 1.27 1.27)) (justify right))
)
(property "Value" "VDC" (id 1) (at 161.29 79.375 0)
(effects (font (size 1.27 1.27)) (justify right))
)
(property "Footprint" "" (id 2) (at 157.48 78.74 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 157.48 78.74 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "V" (id 4) (at 157.48 78.74 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Type" "DC" (id 5) (at 157.48 78.74 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "1 2" (id 6) (at 157.48 78.74 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Params" "dc=5" (id 7) (at 163.83 81.28 0)
(effects (font (size 1.27 1.27)))
)
(pin "1" (uuid 885c89aa-c780-4741-b398-9d4b8e38f094))
(pin "2" (uuid 8a2dca0c-b99f-4109-a426-af5e80ea91fe))
)
(symbol (lib_id "Simulation_SPICE:OPAMP") (at 160.02 91.44 0) (unit 1)
(in_bom yes) (on_board yes)
(uuid 3dd58d42-1028-4fbc-adf4-32d03de981a6)
(property "Reference" "U1" (id 0) (at 165.1 93.98 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "OPAMP" (id 1) (at 165.1 96.52 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 160.02 91.44 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 160.02 91.44 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Name" "uopamp_lvl2" (id 6) (at 160.02 91.44 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Library" "opamp.lib" (id 7) (at 160.02 91.44 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "SUBCKT" (id 8) (at 160.02 91.44 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "1 2 4 5 3" (id 9) (at 160.02 91.44 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid bd8261ed-4ec3-466d-a593-de8cc22438a4))
(pin "2" (uuid 59452a26-a3b6-4a37-a20f-4c2bcc74010e))
(pin "3" (uuid 3b7a7231-9907-49c8-aa51-b9e9b9068d1b))
(pin "4" (uuid b0f744bf-8c76-450e-8cdf-3daee6f0b8a1))
(pin "5" (uuid d981b8b1-dd8d-4890-a039-a934391d8000))
)
(symbol (lib_id "power:GND") (at 144.78 113.665 270) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 71c5abbf-da89-4208-ab90-ab47cb47a86d)
(property "Reference" "#PWR02" (id 0) (at 138.43 113.665 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 140.97 114.3 90)
(effects (font (size 1.27 1.27)) (justify right))
)
(property "Footprint" "" (id 2) (at 144.78 113.665 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 144.78 113.665 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 70c0dc3a-c9e8-4d2a-a705-c6c89d9bebea))
)
(symbol (lib_id "power:GND") (at 157.48 73.66 180) (unit 1)
(in_bom yes) (on_board yes)
(uuid bf78fcdf-1d24-40dc-a76b-1c91df364f4e)
(property "Reference" "#PWR03" (id 0) (at 157.48 67.31 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 161.29 72.39 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 157.48 73.66 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 157.48 73.66 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid d51f887c-ce71-4e7a-9f6c-4362d9b8286a))
)
(symbol (lib_id "power:GND") (at 142.24 101.6 0) (unit 1)
(in_bom yes) (on_board yes)
(uuid c4334e6a-69e5-475f-b5f5-911b3308f64a)
(property "Reference" "#PWR01" (id 0) (at 142.24 107.95 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 142.24 105.41 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 142.24 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 142.24 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 1af0463f-605e-40b1-8e1c-d6b819b8b4f8))
)
(symbol (lib_id "Simulation_SPICE:VDC") (at 157.48 104.14 180) (unit 1)
(in_bom yes) (on_board yes)
(uuid d2018f30-5def-453e-85fe-dac327cfbe9b)
(property "Reference" "V3" (id 0) (at 161.29 102.235 0)
(effects (font (size 1.27 1.27)) (justify right))
)
(property "Value" "VDC" (id 1) (at 161.29 104.775 0)
(effects (font (size 1.27 1.27)) (justify right))
)
(property "Footprint" "" (id 2) (at 157.48 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 157.48 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "V" (id 4) (at 157.48 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Type" "DC" (id 5) (at 157.48 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "1 2" (id 6) (at 157.48 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Params" "dc=5" (id 7) (at 163.83 106.68 0)
(effects (font (size 1.27 1.27)))
)
(pin "1" (uuid 62bdf880-7061-4b86-be3a-09bf959fae21))
(pin "2" (uuid 9bd26aa2-337b-4c5a-a9de-bdab770672a9))
)
(symbol (lib_id "Device:R") (at 148.59 113.665 90) (unit 1)
(in_bom yes) (on_board yes)
(uuid fbe00ebb-3cab-46ea-988c-9e8169e9708f)
(property "Reference" "R1" (id 0) (at 148.59 116.205 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "10K" (id 1) (at 148.59 118.745 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 148.59 115.443 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 148.59 113.665 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid fe3f00f2-cee0-4154-8f20-4097e41e635f))
(pin "2" (uuid 5480c24e-8f90-4441-b07c-0db2096e1071))
)
(sheet_instances
(path "/" (page "1"))
)
(symbol_instances
(path "/c4334e6a-69e5-475f-b5f5-911b3308f64a"
(reference "#PWR01") (unit 1) (value "GND") (footprint "")
)
(path "/71c5abbf-da89-4208-ab90-ab47cb47a86d"
(reference "#PWR02") (unit 1) (value "GND") (footprint "")
)
(path "/bf78fcdf-1d24-40dc-a76b-1c91df364f4e"
(reference "#PWR03") (unit 1) (value "GND") (footprint "")
)
(path "/032a39b4-2686-4cc0-a834-fb52cf55377c"
(reference "#PWR04") (unit 1) (value "GND") (footprint "")
)
(path "/fbe00ebb-3cab-46ea-988c-9e8169e9708f"
(reference "R1") (unit 1) (value "10K") (footprint "")
)
(path "/2a5b0448-42a8-4fa4-9a14-267dc34f9ff7"
(reference "R2") (unit 1) (value "10K") (footprint "")
)
(path "/3dd58d42-1028-4fbc-adf4-32d03de981a6"
(reference "U1") (unit 1) (value "OPAMP") (footprint "")
)
(path "/10f44001-5f65-44eb-a535-b7b3c67d5b83"
(reference "V1") (unit 1) (value "VSIN") (footprint "")
)
(path "/383ea298-1cb3-473e-8fce-19d3c7ac3912"
(reference "V2") (unit 1) (value "VDC") (footprint "")
)
(path "/d2018f30-5def-453e-85fe-dac327cfbe9b"
(reference "V3") (unit 1) (value "VDC") (footprint "")
)
)
)

View File

@ -0,0 +1,120 @@
* Universal Opamp SPICE Macromodels
* Version: v1.1
* Date: 2019-11-23
*
* Written in 2019 by Ste Kulov, HD Retrovision LLC.
* To the extent possible under law, the author(s) have dedicated all copyright
* and related and neighboring rights to this software to the public domain worldwide.
* This software is distributed without any warranty.
* You should have received a copy of the CC0 Public Domain Dedication along with this software.
* If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*
*****************************************
*************
* CHANGELOG *
*************
* ---------------------------------------
* v1.0
* 2019-11-08
* ---------------------------------------
* 1.) Initial Release
* ---------------------------------------
*
*
* ---------------------------------------
* v1.1
* 2019-11-23
* ---------------------------------------
* 1.) lvl2: Removed SW model and replaced all instances with semiconductor diodes.
* 2.) lvl2: Added offsets to the voltage sources to compensate for the new semiconductor junctions.
* ---------------------------------------
*****************************************
*****************************************
.subckt uopamp_lvl1 +IN -IN OUT
* Universal Opamp Level 1
* Single pole opamp without voltage rails and referenced to GND
*
* PINOUT ORDER 1 2 3
* PINOUT ORDER +IN -IN OUT
*
* Parameters:
* Avol => open-loop voltage gain (V/V), default=100k
* GBW => gain-bandwidth product (Hz), default=100meg
* Rin => differential input resistance (ohm), default=100g
* Rout => open-loop output resistance (ohm), default=1
*
R1 +IN -IN {Rin}
G1 0 OUT +IN -IN {Avol/Rout}
R2 OUT 0 100g
C3 OUT 0 {Avol/(2*pi*GBW*Rout)}
.param Avol=100k
.param GBW=100meg
.param Rin=100g
.param Rout=1
.param pi=3.1415926535898
.ends
*****************************************
*****************************************
.subckt uopamp_lvl2 +IN -IN VCC VEE OUT
* Universal Opamp Level 2
* Single pole opamp with rail saturation, current consumption, current limiting, and input offset voltage
*
* PINOUT ORDER 1 2 3 4 5
* PINOUT ORDER +IN -IN VCC VEE OUT
*
* Parameters:
* Avol => open-loop voltage gain (V/V), default=100k
* GBW => gain-bandwidth product (Hz), default=100meg
* Rin => differential input resistance (ohm), default=100g
* Rout => open-loop output resistance (ohm), default=1
* Iq => quiescent supply current (A), default=1m
* Ilimit => maximum output current (A), default=1
* Vrail => voltage between output saturation and each rail (V), default=0
* Vos => input offset voltage (V), default=0
* Vmax => total maximum supply voltage between rails (V), default=50
*
G1 VCC N001 N002 -IN 1u
G2 VEE N001 N002 -IN 1u
R1 VCC N001 {Avol/1u}
R2 N001 VEE {Avol/1u}
G3 OUT VCC VCC N001 {1/(2*Rout)}
G4 VEE OUT N001 VEE {1/(2*Rout)}
R4 VCC OUT {2*Rout}
R5 OUT VEE {2*Rout}
C1 VCC N001 {1u/(2*pi*GBW)}
C2 N001 VEE {1u/(2*pi*GBW)}
G6 N005 VEE N001 OUT {1/(2*Rout)}
G5 N006 VEE OUT N001 {1/(2*Rout)}
R8 -IN +IN {Rin}
V6 VCC N003 {Vrail+545m}
V7 N008 VEE {Vrail+545m}
V8 N002 +IN {Vos}
V9 OUT N007 {Ilimit-545m}
V10 N004 OUT {Ilimit-545m}
D1 N001 N003 diode
D2 N008 N001 diode
D3 VCC N005 diode
D4 VCC N006 diode
D5 VEE N005 zener
D6 VEE N006 zener
D7 N001 N004 diode
D8 N007 N001 diode
I1 VCC VEE {Iq}
.param Avol = 100k
.param GBW = 100meg
.param Rin = 100g
.param Rout = 1
.param Iq = 1m
.param Ilimit = 1
.param Vrail = 0
.param Vos = 0
.param Vmax = 50
.model diode D(Is=1e-14)
.model zener D(Is=1e-14 BV={Vmax})
.param pi=3.1415926535898
.ends
*****************************************

View File

@ -0,0 +1,7 @@
* Some diodes
* Diode 1
.MODEL DIODE1 D (IS=100E-15 RS=10 CJO=1P TT=12N BV=120 IBV=100E-15)
* Diode 2
.MODEL DIODE2 D (IS=100E-15 RS=8 CJO=1.5P TT=11N BV=100 IBV=100E-15)

View File

@ -0,0 +1,7 @@
* Some diodes
* Diode 1
.MODEL DIODE1 D (IS=100E-15 RS=10 CJO=1P TT=12N BV=120 IBV=100E-15)
* Diode 2
.MODEL DIODE2 D (IS=100E-15 RS=8 CJO=1.5P TT=11N BV=100 IBV=100E-15)

View File

@ -0,0 +1,11 @@
.title KiCad schematic
.include "diode.lib"
.save all
.probe alli
.tran 1u 10m
C1 /out GND 10u
R1 /out GND 100k
D1 /in /out DIODE1
V1 /in GND SIN( 0 5 10k )
.end

View File

@ -0,0 +1,2 @@
(kicad_pcb (version 20220308) (generator pcbnew)
)

View File

@ -0,0 +1,331 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.1,
"copper_line_width": 0.2,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"other_line_width": 0.15,
"silk_line_width": 0.15,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"rules": {
"min_copper_edge_clearance": 0.0,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0
},
"track_widths": [],
"via_dimensions": []
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "rectifier.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Spice",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"spice_save_all_currents": true,
"spice_save_all_voltages": true,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"0c9c3a92-6a4e-4a5b-b607-2cfe0f3c4b2e",
""
]
],
"text_variables": {}
}

View File

@ -0,0 +1,467 @@
(kicad_sch (version 20220331) (generator eeschema)
(uuid 0c9c3a92-6a4e-4a5b-b607-2cfe0f3c4b2e)
(paper "A4")
(lib_symbols
(symbol "Device:C" (pin_numbers hide) (pin_names (offset 0.254)) (in_bom yes) (on_board yes)
(property "Reference" "C" (id 0) (at 0.635 2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "C" (id 1) (at 0.635 -2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0.9652 -3.81 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "cap capacitor" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Unpolarized capacitor" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "C_*" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "C_0_1"
(polyline
(pts
(xy -2.032 -0.762)
(xy 2.032 -0.762)
)
(stroke (width 0.508) (type default))
(fill (type none))
)
(polyline
(pts
(xy -2.032 0.762)
(xy 2.032 0.762)
)
(stroke (width 0.508) (type default))
(fill (type none))
)
)
(symbol "C_1_1"
(pin passive line (at 0 3.81 270) (length 2.794)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -3.81 90) (length 2.794)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Device:D" (pin_numbers hide) (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes)
(property "Reference" "D" (id 0) (at 0 2.54 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "D" (id 1) (at 0 -2.54 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "diode" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Diode" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "TO-???* *_Diode_* *SingleDiode* D_*" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "D_0_1"
(polyline
(pts
(xy -1.27 1.27)
(xy -1.27 -1.27)
)
(stroke (width 0.254) (type default))
(fill (type none))
)
(polyline
(pts
(xy 1.27 0)
(xy -1.27 0)
)
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts
(xy 1.27 1.27)
(xy 1.27 -1.27)
(xy -1.27 0)
(xy 1.27 1.27)
)
(stroke (width 0.254) (type default))
(fill (type none))
)
)
(symbol "D_1_1"
(pin passive line (at -3.81 0 0) (length 2.54)
(name "K" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 3.81 0 180) (length 2.54)
(name "A" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes)
(property "Reference" "R" (id 0) (at 2.032 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "R" (id 1) (at 0 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at -1.778 0 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "R res resistor" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Resistor" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "R_*" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "R_0_1"
(rectangle (start -1.016 -2.54) (end 1.016 2.54)
(stroke (width 0.254) (type default))
(fill (type none))
)
)
(symbol "R_1_1"
(pin passive line (at 0 3.81 270) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -3.81 90) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "Simulation_SPICE:VSIN" (pin_numbers hide) (pin_names (offset 0.0254)) (in_bom yes) (on_board yes)
(property "Reference" "V" (id 0) (at 2.54 2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VSIN" (id 1) (at 2.54 0 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Spice_Netlist_Enabled" "Y" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Primitive" "V" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Model" "sin(0 1 1k)" (id 6) (at 2.54 -2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "ki_keywords" "simulation" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Voltage source, sinusoidal" (id 8) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "VSIN_0_0"
(arc (start 0 0) (mid -0.635 0.635) (end -1.27 0)
(stroke (width 0) (type default))
(fill (type none))
)
(arc (start 0 0) (mid 0.635 -0.635) (end 1.27 0)
(stroke (width 0) (type default))
(fill (type none))
)
(text "+" (at 0 1.905 0)
(effects (font (size 1.27 1.27)))
)
)
(symbol "VSIN_0_1"
(circle (center 0 0) (radius 2.54)
(stroke (width 0.254) (type default))
(fill (type background))
)
)
(symbol "VSIN_1_1"
(pin passive line (at 0 5.08 270) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 -5.08 90) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "power:GND" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes)
(property "Reference" "#PWR" (id 0) (at 0 -6.35 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 0 -3.81 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "power-flag" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Power symbol creates a global label with name \"GND\" , ground" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "GND_0_1"
(polyline
(pts
(xy 0 0)
(xy 0 -1.27)
(xy 1.27 -1.27)
(xy 0 -2.54)
(xy -1.27 -1.27)
(xy 0 -1.27)
)
(stroke (width 0) (type default))
(fill (type none))
)
)
(symbol "GND_1_1"
(pin power_in line (at 0 0 270) (length 0) hide
(name "GND" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
)
)
)
(junction (at 155.575 96.52) (diameter 0) (color 0 0 0 0)
(uuid 90298255-a103-4111-b99f-6839e4ed2aa3)
)
(wire (pts (xy 155.575 96.52) (xy 165.1 96.52))
(stroke (width 0) (type default))
(uuid 938ac8bd-5d33-45d4-a671-e203531936df)
)
(wire (pts (xy 134.62 96.52) (xy 147.955 96.52))
(stroke (width 0) (type default))
(uuid f208d8ac-c356-4e7f-8843-f10eed82b140)
)
(text ".tran 1u 10m" (at 134.62 88.265 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid b0eb3c42-1695-4c39-a9fd-fa13617eced3)
)
(label "in" (at 134.62 96.52 0) (fields_autoplaced)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid 0638f2a4-6aba-46f5-93c4-8c70a83aa927)
)
(label "out" (at 165.1 96.52 0) (fields_autoplaced)
(effects (font (size 1.27 1.27)) (justify left bottom))
(uuid 534a5091-dddc-4654-962b-04a61e3980a0)
)
(symbol (lib_id "power:GND") (at 134.62 106.68 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 125bcfd6-fc91-456c-8753-fecb0425cb16)
(property "Reference" "#PWR0103" (id 0) (at 134.62 113.03 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 134.62 111.76 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 134.62 106.68 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 134.62 106.68 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 2e7c6b87-8ca0-4b4f-b706-9b46d00816ac))
)
(symbol (lib_id "power:GND") (at 165.1 104.14 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 2c87bb46-80f5-4e71-b72e-b1b229611c8f)
(property "Reference" "#PWR0101" (id 0) (at 165.1 110.49 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 165.1 109.22 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 165.1 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 165.1 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 280fc63a-0d9f-48b6-95f7-c5e61dae283d))
)
(symbol (lib_id "Simulation_SPICE:VSIN") (at 134.62 101.6 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 2f4ce84c-7613-4135-9bc6-7662b55052cf)
(property "Reference" "V1" (id 0) (at 138.43 99.695 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "VSIN" (id 1) (at 138.43 102.235 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 134.62 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 134.62 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "V" (id 4) (at 134.62 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Type" "SIN" (id 5) (at 134.62 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "1 2" (id 6) (at 134.62 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Params" "dc=0 ampl=5 f=10k" (id 7) (at 134.62 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid a29d8f63-65fa-4d69-b0d4-cfa5c00fc5ab))
(pin "2" (uuid 8bfe05fb-6889-4435-80ba-ab2128b151d8))
)
(symbol (lib_id "Device:C") (at 155.575 100.33 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 36c45a8c-57fb-4d16-8113-60be934d3024)
(property "Reference" "C1" (id 0) (at 159.385 99.695 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "10u" (id 1) (at 159.385 102.235 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 156.5402 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 155.575 100.33 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 0f0333bf-611a-47ec-bd68-52c7b166c571))
(pin "2" (uuid b71649f6-4e0d-4ac7-a45e-e31d214c664b))
)
(symbol (lib_id "Device:D") (at 151.765 96.52 180) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 37eb4620-c4e1-45b7-92da-1117151d60cc)
(property "Reference" "D1" (id 0) (at 151.765 91.44 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "D" (id 1) (at 151.765 93.98 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 151.765 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 151.765 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Device" "DIODE" (id 4) (at 151.765 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Name" "DIODE1" (id 6) (at 151.765 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Library" "diode.lib" (id 7) (at 151.765 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Model_Pins" "2 1" (id 8) (at 151.765 96.52 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid cb1986eb-8b78-41be-ab05-5001090a2a65))
(pin "2" (uuid edfbe61b-6d1d-45a6-bfef-e48a694e79db))
)
(symbol (lib_id "Device:R") (at 165.1 100.33 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid 7ae05049-58f1-4d14-9a95-35ba665c7986)
(property "Reference" "R1" (id 0) (at 167.64 99.695 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "100K" (id 1) (at 167.64 102.235 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 163.322 100.33 90)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (id 3) (at 165.1 100.33 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 908dc772-f335-42cf-8fc9-474d99c97d6b))
(pin "2" (uuid 8284393b-9c35-4de1-912f-0588e9c9883b))
)
(symbol (lib_id "power:GND") (at 155.575 104.14 0) (unit 1)
(in_bom yes) (on_board yes) (fields_autoplaced)
(uuid c5967cbe-0914-4e7b-92aa-1bc61c11d83b)
(property "Reference" "#PWR0102" (id 0) (at 155.575 110.49 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Value" "GND" (id 1) (at 155.575 109.22 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (id 2) (at 155.575 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (id 3) (at 155.575 104.14 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 7706233c-3e24-4ca2-898e-587d4e9865df))
)
(sheet_instances
(path "/" (page "1"))
)
(symbol_instances
(path "/2c87bb46-80f5-4e71-b72e-b1b229611c8f"
(reference "#PWR0101") (unit 1) (value "GND") (footprint "")
)
(path "/c5967cbe-0914-4e7b-92aa-1bc61c11d83b"
(reference "#PWR0102") (unit 1) (value "GND") (footprint "")
)
(path "/125bcfd6-fc91-456c-8753-fecb0425cb16"
(reference "#PWR0103") (unit 1) (value "GND") (footprint "")
)
(path "/36c45a8c-57fb-4d16-8113-60be934d3024"
(reference "C1") (unit 1) (value "10u") (footprint "")
)
(path "/37eb4620-c4e1-45b7-92da-1117151d60cc"
(reference "D1") (unit 1) (value "D") (footprint "")
)
(path "/7ae05049-58f1-4d14-9a95-35ba665c7986"
(reference "R1") (unit 1) (value "100K") (footprint "")
)
(path "/2f4ce84c-7613-4135-9bc6-7662b55052cf"
(reference "V1") (unit 1) (value "VSIN") (footprint "")
)
)
)

View File

@ -56,7 +56,8 @@ set( QA_EESCHEMA_SRCS
test_eagle_plugin.cpp
test_lib_part.cpp
test_netlists.cpp
test_netlist_exporter_kicad.cpp
test_netlist_exporter_spice.cpp
test_ee_item.cpp
test_pin_numbers.cpp
test_sch_pin.cpp

View File

@ -22,6 +22,8 @@
*/
#include "eeschema_test_utils.h"
#include <qa_utils/wx_utils/unit_test_utils.h>
#include <wildcards_and_files_ext.h>
#include <cstdlib>
#include <memory>
@ -30,8 +32,6 @@
#include <eeschema/sch_screen.h>
#include <eeschema/schematic.h>
#include <eeschema/connection_graph.h>
#include <qa_utils/wx_utils/unit_test_utils.h>
#include <wildcards_and_files_ext.h>
#ifndef QA_EESCHEMA_DATA_LOCATION
@ -62,24 +62,58 @@ wxFileName KI_TEST::GetEeschemaTestDataDir()
}
void KI_TEST::SCHEMATIC_TEST_FIXTURE::loadSchematic( const wxString& aRelativePath )
std::unique_ptr<SCHEMATIC> ReadSchematicFromFile( const std::string& aFilename )
{
wxFileName fn = getSchematicFile( aRelativePath );
auto pi = SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD );
std::unique_ptr<SCHEMATIC> schematic = std::make_unique<SCHEMATIC>( nullptr );
BOOST_TEST_MESSAGE( fn.GetFullPath() );
schematic->Reset();
schematic->SetRoot( pi->Load( aFilename, schematic.get() ) );
schematic->CurrentSheet().push_back( &schematic->Root() );
SCH_SCREENS screens( schematic->Root() );
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
screen->UpdateLocalLibSymbolLinks();
SCH_SHEET_LIST sheets = schematic->GetSheets();
// Restore all of the loaded symbol instances from the root sheet screen.
sheets.UpdateSymbolInstances( schematic->RootScreen()->GetSymbolInstances() );
sheets.AnnotatePowerSymbols();
// NOTE: This is required for multi-unit symbols to be correct
// Normally called from SCH_EDIT_FRAME::FixupJunctions() but could be refactored
for( SCH_SHEET_PATH& sheet : sheets )
sheet.UpdateAllScreenReferences();
// NOTE: SchematicCleanUp is not called; QA schematics must already be clean or else
// SchematicCleanUp must be freed from its UI dependencies.
schematic->ConnectionGraph()->Recalculate( sheets, true );
return schematic;
}
template <typename Exporter>
void TEST_NETLIST_EXPORTER_FIXTURE<Exporter>::LoadSchematic( const wxString& aBaseName )
{
wxString fn = GetSchematicPath( aBaseName );
BOOST_TEST_MESSAGE( fn );
wxFileName pro( fn );
pro.SetExt( ProjectFileExtension );
m_schematic.Reset();
m_schematic.CurrentSheet().clear();
m_manager.LoadProject( pro.GetFullPath() );
m_manager.Prj().SetElem( PROJECT::ELEM_SCH_SYMBOL_LIBS, nullptr );
m_schematic.Reset();
m_schematic.SetProject( &m_manager.Prj() );
m_schematic.SetRoot( m_pi->Load( fn.GetFullPath(), &m_schematic ) );
m_schematic.SetRoot( m_pi->Load( fn, &m_schematic ) );
BOOST_REQUIRE_EQUAL( m_pi->GetError().IsEmpty(), true );
@ -94,7 +128,6 @@ void KI_TEST::SCHEMATIC_TEST_FIXTURE::loadSchematic( const wxString& aRelativePa
// Restore all of the loaded symbol instances from the root sheet screen.
sheets.UpdateSymbolInstances( m_schematic.RootScreen()->GetSymbolInstances() );
sheets.UpdateSheetInstances( m_schematic.RootScreen()->GetSheetInstances() );
sheets.AnnotatePowerSymbols();
@ -110,7 +143,8 @@ void KI_TEST::SCHEMATIC_TEST_FIXTURE::loadSchematic( const wxString& aRelativePa
}
wxFileName KI_TEST::SCHEMATIC_TEST_FIXTURE::getSchematicFile( const wxString& aBaseName )
template <typename Exporter>
wxString TEST_NETLIST_EXPORTER_FIXTURE<Exporter>::GetSchematicPath( const wxString& aBaseName )
{
wxFileName fn = KI_TEST::GetEeschemaTestDataDir();
fn.AppendDir( "netlists" );
@ -118,6 +152,46 @@ wxFileName KI_TEST::SCHEMATIC_TEST_FIXTURE::getSchematicFile( const wxString& aB
fn.SetName( aBaseName );
fn.SetExt( KiCadSchematicFileExtension );
return fn;
return fn.GetFullPath();
}
template <typename Exporter>
wxString TEST_NETLIST_EXPORTER_FIXTURE<Exporter>::GetNetlistPath( bool aTest )
{
wxFileName netFile = m_schematic.Prj().GetProjectFullName();
if( aTest )
netFile.SetName( netFile.GetName() + "_test" );
netFile.SetExt( NetlistFileExtension );
return netFile.GetFullPath();
}
template <typename Exporter>
void TEST_NETLIST_EXPORTER_FIXTURE<Exporter>::WriteNetlist()
{
auto exporter = std::make_unique<Exporter>( &m_schematic );
BOOST_REQUIRE_EQUAL( exporter->WriteNetlist( GetNetlistPath( true ), GetNetlistOptions() ),
true );
}
template <typename Exporter>
void TEST_NETLIST_EXPORTER_FIXTURE<Exporter>::Cleanup()
{
wxRemoveFile( GetNetlistPath( true ) );
m_schematic.Reset();
}
template <typename Exporter>
void TEST_NETLIST_EXPORTER_FIXTURE<Exporter>::TestNetlist( const wxString& aBaseName )
{
LoadSchematic( aBaseName );
WriteNetlist();
CompareNetlists();
Cleanup();
}

View File

@ -30,6 +30,18 @@
#include <sch_io_mgr.h>
#include <wx/filename.h>
#include <connection_graph.h>
#include <netlist_exporter_kicad.h>
#include <netlist_exporter_spice.h>
#include <netlist_reader/netlist_reader.h>
#include <netlist_reader/pcb_netlist.h>
#include <project.h>
#include <sch_io_mgr.h>
#include <sch_sheet.h>
#include <schematic.h>
#include <settings/settings_manager.h>
#include <wildcards_and_files_ext.h>
namespace KI_TEST
{
/**
@ -75,4 +87,48 @@ protected:
} // namespace KI_TEST
#endif // QA_EESCHEMA_EESCHEMA_TEST_UTILS__H
template <typename Exporter>
class TEST_NETLIST_EXPORTER_FIXTURE
{
public:
TEST_NETLIST_EXPORTER_FIXTURE() :
m_schematic( nullptr ),
m_pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) ),
m_manager( true )
{
}
virtual ~TEST_NETLIST_EXPORTER_FIXTURE()
{
m_schematic.Reset();
SCH_IO_MGR::ReleasePlugin( m_pi );
}
void LoadSchematic( const wxString& aBaseName );
virtual wxString GetSchematicPath( const wxString& aBaseName );
virtual wxString GetNetlistPath( bool aTest = false );
virtual unsigned GetNetlistOptions() { return 0; }
void WriteNetlist();
virtual void CompareNetlists() = 0;
void Cleanup();
void TestNetlist( const wxString& aBaseName );
///> Schematic to load
SCHEMATIC m_schematic;
SCH_PLUGIN* m_pi;
SETTINGS_MANAGER m_manager;
};
template class TEST_NETLIST_EXPORTER_FIXTURE<NETLIST_EXPORTER_KICAD>;
template class TEST_NETLIST_EXPORTER_FIXTURE<NETLIST_EXPORTER_SPICE>;
#endif // QA_EESCHEMA_EESCHEMA_TEST_UTILS__H

View File

@ -77,6 +77,16 @@ BOOST_AUTO_TEST_CASE( Models )
BOOST_CHECK_EQUAL( modelParamCount, 6 );
BOOST_CHECK_EQUAL( instanceParamCount, 3 );
break;*/
case NGSPICE::MODEL_TYPE::SWITCH:
BOOST_CHECK_EQUAL( modelParamCount, 7 );
BOOST_CHECK_EQUAL( instanceParamCount, 8 );
break;
case NGSPICE::MODEL_TYPE::CSWITCH:
BOOST_CHECK_EQUAL( modelParamCount, 7 );
BOOST_CHECK_EQUAL( instanceParamCount, 7 );
break;
case NGSPICE::MODEL_TYPE::DIODE:
BOOST_CHECK_EQUAL( modelParamCount, 76 );
@ -85,17 +95,17 @@ BOOST_AUTO_TEST_CASE( Models )
case NGSPICE::MODEL_TYPE::BJT:
BOOST_CHECK_EQUAL( modelParamCount, 152 );
BOOST_CHECK_EQUAL( instanceParamCount, 52 );
BOOST_CHECK_EQUAL( instanceParamCount, 53 );
break;
case NGSPICE::MODEL_TYPE::VBIC:
BOOST_CHECK_EQUAL( modelParamCount, 117 );
BOOST_CHECK_EQUAL( instanceParamCount, 44 );
BOOST_CHECK_EQUAL( instanceParamCount, 45 );
break;
case NGSPICE::MODEL_TYPE::HICUM2:
BOOST_CHECK_EQUAL( modelParamCount, 149 );
BOOST_CHECK_EQUAL( instanceParamCount, 60 );
BOOST_CHECK_EQUAL( instanceParamCount, 61 );
break;
case NGSPICE::MODEL_TYPE::JFET:

View File

@ -0,0 +1,175 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020-2021 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, see <http://www.gnu.org/licenses/>.
*/
#include <qa_utils/wx_utils/unit_test_utils.h>
#include <eeschema_test_utils.h>
class TEST_NETLIST_EXPORTER_KICAD_FIXTURE : public TEST_NETLIST_EXPORTER_FIXTURE<NETLIST_EXPORTER_KICAD>
{
public:
void CompareNetlists() override
{
NETLIST golden;
NETLIST test;
{
std::unique_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
&golden, GetNetlistPath(), wxEmptyString ) );
BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
}
{
std::unique_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
&test, GetNetlistPath( true ), wxEmptyString ) );
BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
}
// Number of components should match
BOOST_REQUIRE_EQUAL( golden.GetCount(), test.GetCount() );
for( unsigned i = 0; i < golden.GetCount(); i++ )
{
COMPONENT* goldenComp = golden.GetComponent( i );
COMPONENT* refComp = test.GetComponentByReference( goldenComp->GetReference() );
// Retrieval by reference
BOOST_REQUIRE_NE( refComp, nullptr );
// Retrieval by KIID
KIID_PATH path = goldenComp->GetPath();
BOOST_REQUIRE( !goldenComp->GetKIIDs().empty() );
path.push_back( goldenComp->GetKIIDs().front() );
COMPONENT* pathComp = test.GetComponentByPath( path );
BOOST_REQUIRE_NE( pathComp, nullptr );
// We should have found the same component
BOOST_REQUIRE_EQUAL( refComp->GetReference(), pathComp->GetReference() );
// And that component should have the same number of attached nets
BOOST_REQUIRE_EQUAL( goldenComp->GetNetCount(), refComp->GetNetCount() );
for( unsigned net = 0; net < goldenComp->GetNetCount(); net++ )
{
const COMPONENT_NET& goldenNet = goldenComp->GetNet( net );
const COMPONENT_NET& testNet = refComp->GetNet( net );
// The video test has a bunch of unconnected RESERVED pins which cause duplicate
// auto-generated netnames. The connectivity algo disambiguates these with "_n"
// suffixes, but since the algorithm is multi-threaded, which ones get which suffix
// is not deterministic. So skip these.
if( testNet.GetPinFunction().Contains( "RESERVED" ) )
continue;
// The two nets at the same index should be identical
BOOST_REQUIRE_EQUAL( goldenNet.GetNetName(), testNet.GetNetName() );
BOOST_REQUIRE_EQUAL( goldenNet.GetPinName(), testNet.GetPinName() );
}
}
}
};
BOOST_FIXTURE_TEST_SUITE( Netlists, TEST_NETLIST_EXPORTER_KICAD_FIXTURE )
BOOST_AUTO_TEST_CASE( FindPlugin )
{
BOOST_CHECK_NE( m_pi, nullptr );
}
BOOST_AUTO_TEST_CASE( GlobalPromotion )
{
TestNetlist( "test_global_promotion" );
}
BOOST_AUTO_TEST_CASE( GlobalPromotion2 )
{
TestNetlist( "test_global_promotion_2" );
}
BOOST_AUTO_TEST_CASE( Video )
{
TestNetlist( "video" );
}
BOOST_AUTO_TEST_CASE( ComplexHierarchy )
{
TestNetlist( "complex_hierarchy" );
}
BOOST_AUTO_TEST_CASE( WeakVectorBusDisambiguation )
{
TestNetlist( "weak_vector_bus_disambiguation" );
}
BOOST_AUTO_TEST_CASE( BusJunctions )
{
TestNetlist( "bus_junctions" );
}
BOOST_AUTO_TEST_CASE( HierRenaming )
{
TestNetlist( "test_hier_renaming" );
}
BOOST_AUTO_TEST_CASE( NoConnects )
{
TestNetlist( "noconnects" );
}
BOOST_AUTO_TEST_CASE( PrefixBusAlias )
{
TestNetlist( "prefix_bus_alias" );
}
BOOST_AUTO_TEST_CASE( GroupBusMatching )
{
TestNetlist( "group_bus_matching" );
}
BOOST_AUTO_TEST_CASE( TopLevelHierPins )
{
TestNetlist( "top_level_hier_pins" );
}
BOOST_AUTO_TEST_CASE( BusEntries )
{
TestNetlist( "bus_entries" );
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -0,0 +1,112 @@
/*
* 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 <eeschema_test_utils.h>
#include <netlist_exporter_spice.h>
class TEST_NETLIST_EXPORTER_SPICE_FIXTURE : public TEST_NETLIST_EXPORTER_FIXTURE<NETLIST_EXPORTER_SPICE>
{
public:
wxString GetSchematicPath( const wxString& aBaseName ) override
{
wxFileName fn = KI_TEST::GetEeschemaTestDataDir();
fn.AppendDir( "spice_netlists" );
fn.AppendDir( aBaseName );
fn.SetName( aBaseName );
fn.SetExt( KiCadSchematicFileExtension );
return fn.GetFullPath();
}
wxString GetNetlistPath( bool aTest = false ) override
{
wxFileName netFile = m_schematic.Prj().GetProjectFullName();
if( aTest )
netFile.SetName( netFile.GetName() + "_test" );
netFile.SetExt( "cir" );
return netFile.GetFullPath();
}
void CompareNetlists() override
{
FILE_LINE_READER refReader( GetNetlistPath() );
FILE_LINE_READER resultReader( GetNetlistPath( true ) );
char* refLine = nullptr;
char* resultLine = nullptr;
while( true )
{
refLine = refReader.ReadLine();
resultLine = resultReader.ReadLine();
if( !refLine || !resultReader )
break;
BOOST_REQUIRE_EQUAL( std::string( refReader.Line() ),
std::string( resultReader.Line() ) );
}
BOOST_REQUIRE_EQUAL( std::string( refReader.Line() ),
std::string( resultReader.Line() ) );
}
unsigned GetNetlistOptions() override
{
return NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES
| NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
}
};
BOOST_FIXTURE_TEST_SUITE( NetlistExporterSpice, TEST_NETLIST_EXPORTER_SPICE_FIXTURE )
BOOST_AUTO_TEST_CASE( Rectifier )
{
TestNetlist( "rectifier" );
}
BOOST_AUTO_TEST_CASE( Chirp )
{
TestNetlist( "chirp" );
}
BOOST_AUTO_TEST_CASE( Opamp )
{
TestNetlist( "opamp" );
}
BOOST_AUTO_TEST_CASE( NpnCeAmp )
{
TestNetlist( "npn_ce_amp" );
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -20,136 +20,78 @@
#include <qa_utils/wx_utils/unit_test_utils.h>
#include "eeschema_test_utils.h"
#include <connection_graph.h>
#include <netlist_exporter_kicad.h>
#include <netlist_reader/netlist_reader.h>
#include <netlist_reader/pcb_netlist.h>
#include <project.h>
#include <sch_io_mgr.h>
#include <sch_sheet.h>
#include <schematic.h>
#include <settings/settings_manager.h>
#include <wildcards_and_files_ext.h>
class TEST_NETLISTS_FIXTURE : public KI_TEST::SCHEMATIC_TEST_FIXTURE
class TEST_NETLIST_EXPORTER_KICAD_FIXTURE : publc TEST_NETLIST_EXPORTER_FIXTURE<NETLIST_EXPORTER_KICAD>
{
protected:
wxString getNetlistFileName( bool aTest = false );
public:
void CompareNetlists() override
{
NETLIST golden;
NETLIST test;
void writeNetlist();
{
std::unique_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
&golden, getNetlistFileName(), wxEmptyString ) );
void compareNetlists();
BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
}
void cleanup();
{
std::unique_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
&test, getNetlistFileName( true ), wxEmptyString ) );
void doNetlistTest( const wxString& aBaseName );
BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
}
// Number of components should match
BOOST_REQUIRE_EQUAL( golden.GetCount(), test.GetCount() );
for( unsigned i = 0; i < golden.GetCount(); i++ )
{
COMPONENT* goldenComp = golden.GetComponent( i );
COMPONENT* refComp = test.GetComponentByReference( goldenComp->GetReference() );
// Retrieval by reference
BOOST_REQUIRE_NE( refComp, nullptr );
// Retrieval by KIID
KIID_PATH path = goldenComp->GetPath();
BOOST_REQUIRE( !goldenComp->GetKIIDs().empty() );
path.push_back( goldenComp->GetKIIDs().front() );
COMPONENT* pathComp = test.GetComponentByPath( path );
BOOST_REQUIRE_NE( pathComp, nullptr );
// We should have found the same component
BOOST_REQUIRE_EQUAL( refComp->GetReference(), pathComp->GetReference() );
// And that component should have the same number of attached nets
BOOST_REQUIRE_EQUAL( goldenComp->GetNetCount(), refComp->GetNetCount() );
for( unsigned net = 0; net < goldenComp->GetNetCount(); net++ )
{
const COMPONENT_NET& goldenNet = goldenComp->GetNet( net );
const COMPONENT_NET& testNet = refComp->GetNet( net );
// The video test has a bunch of unconnected RESERVED pins which cause duplicate
// auto-generated netnames. The connectivity algo disambiguates these with "_n"
// suffixes, but since the algorithm is multi-threaded, which ones get which suffix
// is not deterministic. So skip these.
if( testNet.GetPinFunction().Contains( "RESERVED" ) )
continue;
// The two nets at the same index should be identical
BOOST_REQUIRE_EQUAL( goldenNet.GetNetName(), testNet.GetNetName() );
BOOST_REQUIRE_EQUAL( goldenNet.GetPinName(), testNet.GetPinName() );
}
}
}
};
wxString TEST_NETLISTS_FIXTURE::getNetlistFileName( bool aTest )
{
wxFileName netFile = m_schematic.Prj().GetProjectFullName();
if( aTest )
netFile.SetName( netFile.GetName() + "_test" );
netFile.SetExt( NetlistFileExtension );
return netFile.GetFullPath();
}
void TEST_NETLISTS_FIXTURE::writeNetlist()
{
auto exporter = std::make_unique<NETLIST_EXPORTER_KICAD>( &m_schematic );
BOOST_REQUIRE_EQUAL( exporter->WriteNetlist( getNetlistFileName( true ), 0 ), true );
}
void TEST_NETLISTS_FIXTURE::compareNetlists()
{
NETLIST golden;
NETLIST test;
{
std::unique_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
&golden, getNetlistFileName(), wxEmptyString ) );
BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
}
{
std::unique_ptr<NETLIST_READER> netlistReader( NETLIST_READER::GetNetlistReader(
&test, getNetlistFileName( true ), wxEmptyString ) );
BOOST_REQUIRE_NO_THROW( netlistReader->LoadNetlist() );
}
// Number of components should match
BOOST_REQUIRE_EQUAL( golden.GetCount(), test.GetCount() );
for( unsigned i = 0; i < golden.GetCount(); i++ )
{
COMPONENT* goldenComp = golden.GetComponent( i );
COMPONENT* refComp = test.GetComponentByReference( goldenComp->GetReference() );
// Retrieval by reference
BOOST_REQUIRE_NE( refComp, nullptr );
// Retrieval by KIID
KIID_PATH path = goldenComp->GetPath();
BOOST_REQUIRE( !goldenComp->GetKIIDs().empty() );
path.push_back( goldenComp->GetKIIDs().front() );
COMPONENT* pathComp = test.GetComponentByPath( path );
BOOST_REQUIRE_NE( pathComp, nullptr );
// We should have found the same component
BOOST_REQUIRE_EQUAL( refComp->GetReference(), pathComp->GetReference() );
// And that component should have the same number of attached nets
BOOST_REQUIRE_EQUAL( goldenComp->GetNetCount(), refComp->GetNetCount() );
for( unsigned net = 0; net < goldenComp->GetNetCount(); net++ )
{
const COMPONENT_NET& goldenNet = goldenComp->GetNet( net );
const COMPONENT_NET& testNet = refComp->GetNet( net );
// The video test has a bunch of unconnected RESERVED pins which cause duplicate
// auto-generated netnames. The connectivity algo disambiguates these with "_n"
// suffixes, but since the algorithm is multi-threaded, which ones get which suffix
// is not deterministic. So skip these.
if( testNet.GetPinFunction().Contains( "RESERVED" ) )
continue;
// The two nets at the same index should be identical
BOOST_REQUIRE_EQUAL( goldenNet.GetNetName(), testNet.GetNetName() );
BOOST_REQUIRE_EQUAL( goldenNet.GetPinName(), testNet.GetPinName() );
}
}
}
void TEST_NETLISTS_FIXTURE::cleanup()
{
wxRemoveFile( getNetlistFileName( true ) );
m_schematic.Reset();
}
void TEST_NETLISTS_FIXTURE::doNetlistTest( const wxString& aBaseName )
{
loadSchematic( aBaseName );
writeNetlist();
compareNetlists();
cleanup();
}
BOOST_FIXTURE_TEST_SUITE( Netlists, TEST_NETLISTS_FIXTURE )
BOOST_FIXTURE_TEST_SUITE( Netlists, TEST_NETLIST_EXPORTER_KICAD_FIXTURE )
BOOST_AUTO_TEST_CASE( FindPlugin )