Sim: Ibis improvements and fixes

Follow-up after the KIBIS and KIBIS GUI merge requests.

- Move KIBIS from Pcbnew to Eeschema space,
- Make KIBIS obtain the Ku/Kd coefficients via the `SPICE_SIMULATOR` class instead of calling the `ngspice` executable via `system()`,
- Allow to toggle between differential and single-ended model in the GUI,
- Various GUI fixes and improvements.
This commit is contained in:
Fabien Corona 2022-10-25 09:45:40 +00:00 committed by Mikolaj Wielgus
parent 6794b0f4f9
commit 20b63f305e
21 changed files with 478 additions and 206 deletions

View File

@ -35,7 +35,7 @@ Licensed in the public domain:
Licensed under CC BY-SA 4.0: Licensed under CC BY-SA 4.0:
- All the demo files provided in demos/* - All the demo files provided in demos/*
Licensed under clause-3 BSD: Licensed under clause-3 BSD:
- ibis / kibis files in pcbnew/signalIntegrity - ibis / kibis files in eeschema/sim/kibis
Licensed under CC0 Licensed under CC0
- uopamp.lib.spice in some directories in qa/data/eeschema/spice_netlists/ - uopamp.lib.spice in some directories in qa/data/eeschema/spice_netlists/
Licensed under GPLv3 (or later): Licensed under GPLv3 (or later):

View File

@ -276,8 +276,6 @@ set( EESCHEMA_SRCS
sch_plugins/database/sch_database_plugin.cpp sch_plugins/database/sch_database_plugin.cpp
${CMAKE_SOURCE_DIR}/pcbnew/ibis/ibis_parser.cpp
${CMAKE_SOURCE_DIR}/pcbnew/ibis/kibis.cpp
# Some simulation features must be built even if libngspice is not linked. # Some simulation features must be built even if libngspice is not linked.
sim/sim_library.cpp sim/sim_library.cpp
@ -305,6 +303,9 @@ set( EESCHEMA_SRCS
sim/spice_library_parser.cpp sim/spice_library_parser.cpp
sim/spice_model_parser.cpp sim/spice_model_parser.cpp
sim/kibis/ibis_parser.cpp
sim/kibis/kibis.cpp
tools/assign_footprints.cpp tools/assign_footprints.cpp
tools/backannotate.cpp tools/backannotate.cpp
tools/ee_actions.cpp tools/ee_actions.cpp

View File

@ -165,6 +165,17 @@ bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
m_ibisModelCombobox->SetStringSelection( m_ibisModelCombobox->SetStringSelection(
SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY_KIBIS::MODEL_FIELD ) ); SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY_KIBIS::MODEL_FIELD ) );
} }
if( SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1" )
{
kibismodel->SwitchSingleEndedDiff( true );
m_differentialCheckbox->SetValue( true );
}
else
{
kibismodel->SwitchSingleEndedDiff( false );
m_differentialCheckbox->SetValue( false );
}
} }
} }
} }
@ -235,13 +246,16 @@ bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
m_libraryModels.at( m_modelNameCombobox->GetSelection() ) ); m_libraryModels.at( m_modelNameCombobox->GetSelection() ) );
if( kibismodel ) if( kibismodel )
{ {
SIM_MODEL::SetFieldValue( SIM_MODEL::SetFieldValue(
m_fields, SIM_LIBRARY_KIBIS::PIN_FIELD, m_fields, SIM_LIBRARY_KIBIS::PIN_FIELD,
kibismodel->GetIbisPins().at( m_ibisPinCombobox->GetSelection() ).first ); kibismodel->GetIbisPins().at( m_ibisPinCombobox->GetSelection() ).first );
SIM_MODEL::SetFieldValue( m_fields, SIM_LIBRARY_KIBIS::MODEL_FIELD, SIM_MODEL::SetFieldValue( m_fields, SIM_LIBRARY_KIBIS::MODEL_FIELD,
std::string( m_ibisModelCombobox->GetValue().c_str() ) ); std::string( m_ibisModelCombobox->GetValue().c_str() ) );
SIM_MODEL::SetFieldValue(
m_fields, SIM_LIBRARY_KIBIS::DIFF_FIELD,
( kibismodel->CanDifferential() && m_differentialCheckbox->GetValue() ) ? "1"
: "" );
} }
} }
@ -280,12 +294,47 @@ void DIALOG_SIM_MODEL<T>::updateWidgets()
template <typename T> template <typename T>
void DIALOG_SIM_MODEL<T>::updateIbisWidgets() void DIALOG_SIM_MODEL<T>::updateIbisWidgets()
{ {
SIM_MODEL_KIBIS* modelkibis = nullptr;
if( isIbisLoaded() )
{
modelkibis = dynamic_cast<SIM_MODEL_KIBIS*>( &curModel() );
for ( auto& item : m_sourceSizer->GetChildren() )
{
if ( item->GetWindow() == m_differentialCheckbox )
{
item->SetFlag( wxALIGN_CENTER_VERTICAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN );
}
if ( item->GetWindow() == m_overrideCheckbox )
{
item->SetFlag( wxALIGN_CENTER_VERTICAL|wxALL );
}
}
}
else
{
for ( auto& item : m_sourceSizer->GetChildren() )
{
if ( item->GetWindow() == m_differentialCheckbox )
{
item->SetFlag( wxALIGN_CENTER_VERTICAL|wxALL );
}
if ( item->GetWindow() == m_overrideCheckbox )
{
item->SetFlag( wxALIGN_CENTER_VERTICAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN );
}
}
}
m_ibisModelCombobox->Show( isIbisLoaded() ); m_ibisModelCombobox->Show( isIbisLoaded() );
m_ibisPinCombobox->Show( isIbisLoaded() ); m_ibisPinCombobox->Show( isIbisLoaded() );
m_ibisModelLabel->Show( isIbisLoaded() ); m_ibisModelLabel->Show( isIbisLoaded() );
m_ibisPinLabel->Show( isIbisLoaded() ); m_ibisPinLabel->Show( isIbisLoaded() );
m_overrideCheckbox->Show( !isIbisLoaded() ); m_overrideCheckbox->Show( !isIbisLoaded() );
m_differentialCheckbox->Show( isIbisLoaded() && modelkibis && modelkibis->CanDifferential() );
m_modelNameLabel->SetLabel( isIbisLoaded() ? "Component:" : "Model:" ); m_modelNameLabel->SetLabel( isIbisLoaded() ? "Component:" : "Model:" );
} }
@ -554,6 +603,7 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aFilePath )
{ {
wxString ibisTypeString = SIM_MODEL::GetFieldValue( &m_fields, SIM_MODEL::TYPE_FIELD ); wxString ibisTypeString = SIM_MODEL::GetFieldValue( &m_fields, SIM_MODEL::TYPE_FIELD );
SIM_MODEL::TYPE ibisType = SIM_MODEL::TYPE::KIBIS_DEVICE; SIM_MODEL::TYPE ibisType = SIM_MODEL::TYPE::KIBIS_DEVICE;
if( ibisTypeString == "IBISDRIVERDC" ) if( ibisTypeString == "IBISDRIVERDC" )
@ -562,10 +612,6 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aFilePath )
ibisType = SIM_MODEL::TYPE::KIBIS_DRIVER_RECT; ibisType = SIM_MODEL::TYPE::KIBIS_DRIVER_RECT;
else if( ibisTypeString == "IBISDRIVRPRBS" ) else if( ibisTypeString == "IBISDRIVRPRBS" )
ibisType = SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS; ibisType = SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS;
else if( ibisTypeString == "IBISDIFFDEVICE" )
ibisType = SIM_MODEL::TYPE::KIBIS_DIFFDEVICE;
else if( ibisTypeString == "IBISDIFFDRIVER" )
ibisType = SIM_MODEL::TYPE::KIBIS_DIFFDRIVER;
std::dynamic_pointer_cast<SIM_LIBRARY_KIBIS>( m_library ) std::dynamic_pointer_cast<SIM_LIBRARY_KIBIS>( m_library )
->ReadFile( std::string( absolutePath.ToUTF8() ), ibisType ); ->ReadFile( std::string( absolutePath.ToUTF8() ), ibisType );
@ -986,8 +1032,13 @@ void DIALOG_SIM_MODEL<T>::onIbisPinCombobox( wxCommandEvent& aEvent )
} }
std::vector<std::pair<std::string, std::string>> strs = modelkibis->GetIbisPins(); std::vector<std::pair<std::string, std::string>> strs = modelkibis->GetIbisPins();
std::string pinNumber = strs.at( m_ibisPinCombobox->GetSelection() ).first;
modelkibis->ChangePin( *std::dynamic_pointer_cast<SIM_LIBRARY_KIBIS>( m_library ), modelkibis->ChangePin( *std::dynamic_pointer_cast<SIM_LIBRARY_KIBIS>( m_library ),
strs.at( m_ibisPinCombobox->GetSelection() ).first ); pinNumber );
modelkibis->m_enableDiff = dynamic_cast<SIM_LIBRARY_KIBIS*>( m_library.get() )
->isPinDiff( modelkibis->GetComponentName(), pinNumber );
for( wxString modelName : modelkibis->GetIbisModels() ) for( wxString modelName : modelkibis->GetIbisModels() )
modelLabels.Add( modelName ); modelLabels.Add( modelName );
@ -1030,6 +1081,18 @@ void DIALOG_SIM_MODEL<T>::onOverrideCheckbox( wxCommandEvent& aEvent )
updateWidgets(); updateWidgets();
} }
template <typename T>
void DIALOG_SIM_MODEL<T>::onDifferentialCheckbox( wxCommandEvent& aEvent )
{
if( isIbisLoaded() )
{
SIM_MODEL_KIBIS* modelkibis = dynamic_cast<SIM_MODEL_KIBIS*>( &curModel() );
bool diff = m_differentialCheckbox->GetValue() && modelkibis->CanDifferential();
modelkibis->SwitchSingleEndedDiff( diff );
}
updateWidgets();
}
template <typename T> template <typename T>
void DIALOG_SIM_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent ) void DIALOG_SIM_MODEL<T>::onDeviceTypeChoice( wxCommandEvent& aEvent )
@ -1059,9 +1122,7 @@ void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
&& ( type == SIM_MODEL::TYPE::KIBIS_DEVICE && ( type == SIM_MODEL::TYPE::KIBIS_DEVICE
|| type == SIM_MODEL::TYPE::KIBIS_DRIVER_DC || type == SIM_MODEL::TYPE::KIBIS_DRIVER_DC
|| type == SIM_MODEL::TYPE::KIBIS_DRIVER_RECT || type == SIM_MODEL::TYPE::KIBIS_DRIVER_RECT
|| type == SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS || type == SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS ) )
|| type == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE
|| type == SIM_MODEL::TYPE::KIBIS_DIFFDRIVER ) )
{ {
std::shared_ptr<SIM_MODEL_KIBIS> kibismodel = std::shared_ptr<SIM_MODEL_KIBIS> kibismodel =
std::dynamic_pointer_cast<SIM_MODEL_KIBIS>( std::dynamic_pointer_cast<SIM_MODEL_KIBIS>(
@ -1070,12 +1131,6 @@ void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
m_libraryModels.at( m_modelNameCombobox->GetSelection() ) = m_libraryModels.at( m_modelNameCombobox->GetSelection() ) =
std::shared_ptr<SIM_MODEL>( dynamic_cast<SIM_MODEL*>( std::shared_ptr<SIM_MODEL>( dynamic_cast<SIM_MODEL*>(
new SIM_MODEL_KIBIS( type, *kibismodel, m_fields ) ) ); new SIM_MODEL_KIBIS( type, *kibismodel, m_fields ) ) );
wxCommandEvent dummyEvent;
onIbisPinCombobox( dummyEvent );
kibismodel = std::dynamic_pointer_cast<SIM_MODEL_KIBIS>(
m_libraryModels.at( m_modelNameCombobox->GetSelection() ) );
} }
m_curModelType = type; m_curModelType = type;

View File

@ -24,7 +24,7 @@
#ifndef DIALOG_SIM_MODEL_H #ifndef DIALOG_SIM_MODEL_H
#define DIALOG_SIM_MODEL_H #define DIALOG_SIM_MODEL_H
#include <../../pcbnew/ibis/kibis.h> #include <sim/kibis/kibis.h>
#include <dialog_sim_model_base.h> #include <dialog_sim_model_base.h>
#include <netlist_exporter_spice.h> #include <netlist_exporter_spice.h>
@ -123,6 +123,7 @@ private:
void onOverrideCheckboxUpdate( wxUpdateUIEvent& aEvent ) override; void onOverrideCheckboxUpdate( wxUpdateUIEvent& aEvent ) override;
void onDeviceTypeChoiceUpdate( wxUpdateUIEvent& aEvent ) override; void onDeviceTypeChoiceUpdate( wxUpdateUIEvent& aEvent ) override;
void onTypeChoiceUpdate( wxUpdateUIEvent& aEvent ) override; void onTypeChoiceUpdate( wxUpdateUIEvent& aEvent ) override;
void onDifferentialCheckbox( wxCommandEvent& event ) override;
void onParamGridSetFocus( wxFocusEvent& aEvent ); void onParamGridSetFocus( wxFocusEvent& aEvent );
void onParamGridSelectionChange( wxPropertyGridEvent& aEvent ); void onParamGridSelectionChange( wxPropertyGridEvent& aEvent );

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5) // C++ code generated with wxFormBuilder (version 3.10.1-88b0f50)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -23,68 +23,66 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
wxBoxSizer* bSizer9; wxBoxSizer* bSizer9;
bSizer9 = new wxBoxSizer( wxVERTICAL ); bSizer9 = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbSizer4; m_sourceStaticSizer = new wxStaticBoxSizer( new wxStaticBox( m_modelPanel, wxID_ANY, _("Source") ), wxVERTICAL );
sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( m_modelPanel, wxID_ANY, _("Source") ), wxVERTICAL );
wxFlexGridSizer* fgSizer15; m_sourceSizer = new wxFlexGridSizer( 0, 4, 0, 0 );
fgSizer15 = new wxFlexGridSizer( 0, 4, 0, 0 ); m_sourceSizer->AddGrowableCol( 2 );
fgSizer15->AddGrowableCol( 2 ); m_sourceSizer->SetFlexibleDirection( wxBOTH );
fgSizer15->SetFlexibleDirection( wxBOTH ); m_sourceSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
fgSizer15->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_useInstanceModelRadioButton = new wxRadioButton( sbSizer4->GetStaticBox(), wxID_ANY, _("Instance"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); m_useInstanceModelRadioButton = new wxRadioButton( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, _("Instance"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
fgSizer15->Add( m_useInstanceModelRadioButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); m_sourceSizer->Add( m_useInstanceModelRadioButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_useLibraryModelRadioButton = new wxRadioButton( sbSizer4->GetStaticBox(), wxID_ANY, _("Library:"), wxDefaultPosition, wxDefaultSize, 0 ); m_useLibraryModelRadioButton = new wxRadioButton( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, _("Library:"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer15->Add( m_useLibraryModelRadioButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); m_sourceSizer->Add( m_useLibraryModelRadioButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_tclibraryPathName = new wxTextCtrl( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); m_tclibraryPathName = new wxTextCtrl( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
fgSizer15->Add( m_tclibraryPathName, 0, wxEXPAND|wxALL, 5 ); m_sourceSizer->Add( m_tclibraryPathName, 0, wxEXPAND|wxALL, 5 );
m_browseButton = new wxBitmapButton( sbSizer4->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); m_browseButton = new wxBitmapButton( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
fgSizer15->Add( m_browseButton, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); m_sourceSizer->Add( m_browseButton, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
fgSizer15->Add( 0, 0, 1, wxEXPAND, 5 ); m_sourceSizer->Add( 0, 0, 1, wxEXPAND, 5 );
m_modelNameLabel = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, _("Model:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); m_modelNameLabel = new wxStaticText( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, _("Model:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
m_modelNameLabel->Wrap( -1 ); m_modelNameLabel->Wrap( -1 );
fgSizer15->Add( m_modelNameLabel, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); m_sourceSizer->Add( m_modelNameLabel, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_modelNameCombobox = new wxComboBox( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxTE_PROCESS_ENTER ); m_modelNameCombobox = new wxComboBox( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxTE_PROCESS_ENTER );
fgSizer15->Add( m_modelNameCombobox, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); m_sourceSizer->Add( m_modelNameCombobox, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
m_overrideCheckbox = new wxCheckBox( sbSizer4->GetStaticBox(), wxID_ANY, _("Override"), wxDefaultPosition, wxDefaultSize, 0 ); m_overrideCheckbox = new wxCheckBox( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, _("Override"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer15->Add( m_overrideCheckbox, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_sourceSizer->Add( m_overrideCheckbox, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
fgSizer15->Add( 0, 0, 1, wxEXPAND, 5 ); m_sourceSizer->Add( 0, 0, 1, wxEXPAND, 5 );
m_ibisPinLabel = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, _("Pin:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); m_ibisPinLabel = new wxStaticText( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, _("Pin:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
m_ibisPinLabel->Wrap( -1 ); m_ibisPinLabel->Wrap( -1 );
fgSizer15->Add( m_ibisPinLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 ); m_sourceSizer->Add( m_ibisPinLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
m_ibisPinCombobox = new wxComboBox( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxTE_PROCESS_ENTER ); m_ibisPinCombobox = new wxComboBox( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxTE_PROCESS_ENTER );
fgSizer15->Add( m_ibisPinCombobox, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); m_sourceSizer->Add( m_ibisPinCombobox, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
m_differentialCheckbox = new wxCheckBox( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, _("Differential"), wxDefaultPosition, wxDefaultSize, 0 );
m_sourceSizer->Add( m_differentialCheckbox, 0, wxALL, 5 );
fgSizer15->Add( 0, 0, 1, wxEXPAND, 5 ); m_sourceSizer->Add( 0, 0, 1, wxEXPAND, 5 );
m_ibisModelLabel = new wxStaticText( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, _("Model:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
fgSizer15->Add( 0, 0, 1, wxEXPAND, 5 );
m_ibisModelLabel = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, _("Model:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
m_ibisModelLabel->Wrap( -1 ); m_ibisModelLabel->Wrap( -1 );
fgSizer15->Add( m_ibisModelLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 ); m_sourceSizer->Add( m_ibisModelLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 );
m_ibisModelCombobox = new wxComboBox( sbSizer4->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxTE_PROCESS_ENTER ); m_ibisModelCombobox = new wxComboBox( m_sourceStaticSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxTE_PROCESS_ENTER );
fgSizer15->Add( m_ibisModelCombobox, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); m_sourceSizer->Add( m_ibisModelCombobox, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
sbSizer4->Add( fgSizer15, 0, wxEXPAND, 5 ); m_sourceStaticSizer->Add( m_sourceSizer, 0, wxEXPAND, 5 );
bSizer9->Add( sbSizer4, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 ); bSizer9->Add( m_sourceStaticSizer, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
wxStaticBoxSizer* sbSizer5; wxStaticBoxSizer* sbSizer5;
sbSizer5 = new wxStaticBoxSizer( new wxStaticBox( m_modelPanel, wxID_ANY, _("Model") ), wxVERTICAL ); sbSizer5 = new wxStaticBoxSizer( new wxStaticBox( m_modelPanel, wxID_ANY, _("Model") ), wxVERTICAL );
@ -279,6 +277,8 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
m_ibisPinCombobox->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxKillFocus ), NULL, this ); m_ibisPinCombobox->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxKillFocus ), NULL, this );
m_ibisPinCombobox->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisPinComboboxTextEnter ), NULL, this ); m_ibisPinCombobox->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisPinComboboxTextEnter ), NULL, this );
m_ibisPinCombobox->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this ); m_ibisPinCombobox->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this );
m_differentialCheckbox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onDifferentialCheckbox ), NULL, this );
m_differentialCheckbox->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onOverrideCheckboxUpdate ), NULL, this );
m_ibisModelCombobox->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisModelCombobox ), NULL, this ); m_ibisModelCombobox->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisModelCombobox ), NULL, this );
m_ibisModelCombobox->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxKillFocus ), NULL, this ); m_ibisModelCombobox->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxKillFocus ), NULL, this );
m_ibisModelCombobox->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisModelComboboxTextEnter ), NULL, this ); m_ibisModelCombobox->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisModelComboboxTextEnter ), NULL, this );
@ -313,6 +313,8 @@ DIALOG_SIM_MODEL_BASE::~DIALOG_SIM_MODEL_BASE()
m_ibisPinCombobox->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxKillFocus ), NULL, this ); m_ibisPinCombobox->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxKillFocus ), NULL, this );
m_ibisPinCombobox->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisPinComboboxTextEnter ), NULL, this ); m_ibisPinCombobox->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisPinComboboxTextEnter ), NULL, this );
m_ibisPinCombobox->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this ); m_ibisPinCombobox->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxUpdate ), NULL, this );
m_differentialCheckbox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onDifferentialCheckbox ), NULL, this );
m_differentialCheckbox->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onOverrideCheckboxUpdate ), NULL, this );
m_ibisModelCombobox->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisModelCombobox ), NULL, this ); m_ibisModelCombobox->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisModelCombobox ), NULL, this );
m_ibisModelCombobox->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxKillFocus ), NULL, this ); m_ibisModelCombobox->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameComboboxKillFocus ), NULL, this );
m_ibisModelCombobox->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisModelComboboxTextEnter ), NULL, this ); m_ibisModelCombobox->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onIbisModelComboboxTextEnter ), NULL, this );

View File

@ -186,31 +186,31 @@
<property name="id">wxID_ANY</property> <property name="id">wxID_ANY</property>
<property name="label">Source</property> <property name="label">Source</property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">sbSizer4</property> <property name="name">m_sourceStaticSizer</property>
<property name="orient">wxVERTICAL</property> <property name="orient">wxVERTICAL</property>
<property name="parent">1</property> <property name="parent">1</property>
<property name="permission">none</property> <property name="permission">protected</property>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND</property> <property name="flag">wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxFlexGridSizer" expanded="1"> <object class="wxFlexGridSizer" expanded="0">
<property name="cols">4</property> <property name="cols">4</property>
<property name="flexible_direction">wxBOTH</property> <property name="flexible_direction">wxBOTH</property>
<property name="growablecols">2</property> <property name="growablecols">2</property>
<property name="growablerows"></property> <property name="growablerows"></property>
<property name="hgap">0</property> <property name="hgap">0</property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">fgSizer15</property> <property name="name">m_sourceSizer</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property> <property name="permission">protected</property>
<property name="rows">0</property> <property name="rows">0</property>
<property name="vgap">0</property> <property name="vgap">0</property>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxRadioButton" expanded="1"> <object class="wxRadioButton" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -271,11 +271,11 @@
<event name="OnRadioButton">onRadioButton</event> <event name="OnRadioButton">onRadioButton</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxRadioButton" expanded="1"> <object class="wxRadioButton" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -336,11 +336,11 @@
<event name="OnRadioButton">onRadioButton</event> <event name="OnRadioButton">onRadioButton</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property> <property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1"> <object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -401,11 +401,11 @@
<event name="OnUpdateUI">onLibraryPathUpdate</event> <event name="OnUpdateUI">onLibraryPathUpdate</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property> <property name="flag">wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxBitmapButton" expanded="1"> <object class="wxBitmapButton" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -476,11 +476,11 @@
<event name="OnUpdateUI">onBrowseButtonUpdate</event> <event name="OnUpdateUI">onBrowseButtonUpdate</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND</property> <property name="flag">wxEXPAND</property>
<property name="proportion">1</property> <property name="proportion">1</property>
<object class="spacer" expanded="1"> <object class="spacer" expanded="0">
<property name="height">0</property> <property name="height">0</property>
<property name="permission">protected</property> <property name="permission">protected</property>
<property name="width">0</property> <property name="width">0</property>
@ -547,11 +547,11 @@
<property name="wrap">-1</property> <property name="wrap">-1</property>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxComboBox" expanded="1"> <object class="wxComboBox" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -616,11 +616,11 @@
<event name="OnUpdateUI">onModelNameComboboxUpdate</event> <event name="OnUpdateUI">onModelNameComboboxUpdate</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxCheckBox" expanded="1"> <object class="wxCheckBox" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -682,21 +682,21 @@
<event name="OnUpdateUI">onOverrideCheckboxUpdate</event> <event name="OnUpdateUI">onOverrideCheckboxUpdate</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND</property> <property name="flag">wxEXPAND</property>
<property name="proportion">1</property> <property name="proportion">1</property>
<object class="spacer" expanded="1"> <object class="spacer" expanded="0">
<property name="height">0</property> <property name="height">0</property>
<property name="permission">protected</property> <property name="permission">protected</property>
<property name="width">0</property> <property name="width">0</property>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxStaticText" expanded="1"> <object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -753,11 +753,11 @@
<property name="wrap">-1</property> <property name="wrap">-1</property>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxComboBox" expanded="1"> <object class="wxComboBox" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -822,31 +822,87 @@
<event name="OnUpdateUI">onModelNameComboboxUpdate</event> <event name="OnUpdateUI">onModelNameComboboxUpdate</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Differential</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_differentialCheckbox</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnCheckBox">onDifferentialCheckbox</event>
<event name="OnUpdateUI">onOverrideCheckboxUpdate</event>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND</property> <property name="flag">wxEXPAND</property>
<property name="proportion">1</property> <property name="proportion">1</property>
<object class="spacer" expanded="1"> <object class="spacer" expanded="0">
<property name="height">0</property> <property name="height">0</property>
<property name="permission">protected</property> <property name="permission">protected</property>
<property name="width">0</property> <property name="width">0</property>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxStaticText" expanded="1"> <object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -903,11 +959,11 @@
<property name="wrap">-1</property> <property name="wrap">-1</property>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxComboBox" expanded="1"> <object class="wxComboBox" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5) // C++ code generated with wxFormBuilder (version 3.10.1-88b0f50)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -54,6 +54,8 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
protected: protected:
wxNotebook* m_notebook; wxNotebook* m_notebook;
wxPanel* m_modelPanel; wxPanel* m_modelPanel;
wxStaticBoxSizer* m_sourceStaticSizer;
wxFlexGridSizer* m_sourceSizer;
wxRadioButton* m_useInstanceModelRadioButton; wxRadioButton* m_useInstanceModelRadioButton;
wxRadioButton* m_useLibraryModelRadioButton; wxRadioButton* m_useLibraryModelRadioButton;
wxTextCtrl* m_tclibraryPathName; wxTextCtrl* m_tclibraryPathName;
@ -63,6 +65,7 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
wxCheckBox* m_overrideCheckbox; wxCheckBox* m_overrideCheckbox;
wxStaticText* m_ibisPinLabel; wxStaticText* m_ibisPinLabel;
wxComboBox* m_ibisPinCombobox; wxComboBox* m_ibisPinCombobox;
wxCheckBox* m_differentialCheckbox;
wxStaticText* m_ibisModelLabel; wxStaticText* m_ibisModelLabel;
wxComboBox* m_ibisModelCombobox; wxComboBox* m_ibisModelCombobox;
wxNotebook* m_notebook4; wxNotebook* m_notebook4;
@ -97,6 +100,7 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
virtual void onOverrideCheckboxUpdate( wxUpdateUIEvent& event ) { event.Skip(); } virtual void onOverrideCheckboxUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onIbisPinCombobox( wxCommandEvent& event ) { event.Skip(); } virtual void onIbisPinCombobox( wxCommandEvent& event ) { event.Skip(); }
virtual void onIbisPinComboboxTextEnter( wxCommandEvent& event ) { event.Skip(); } virtual void onIbisPinComboboxTextEnter( wxCommandEvent& event ) { event.Skip(); }
virtual void onDifferentialCheckbox( wxCommandEvent& event ) { event.Skip(); }
virtual void onIbisModelCombobox( wxCommandEvent& event ) { event.Skip(); } virtual void onIbisModelCombobox( wxCommandEvent& event ) { event.Skip(); }
virtual void onIbisModelComboboxTextEnter( wxCommandEvent& event ) { event.Skip(); } virtual void onIbisModelComboboxTextEnter( wxCommandEvent& event ) { event.Skip(); }
virtual void onDeviceTypeChoice( wxCommandEvent& event ) { event.Skip(); } virtual void onDeviceTypeChoice( wxCommandEvent& event ) { event.Skip(); }

View File

@ -23,7 +23,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <../../pcbnew/ibis/kibis.h> #include <sim/kibis/kibis.h>
#include "netlist_exporter_spice.h" #include "netlist_exporter_spice.h"
#include <sim/sim_library_spice.h> #include <sim/sim_library_spice.h>
#include <sim/sim_model_raw_spice.h> #include <sim/sim_model_raw_spice.h>
@ -403,7 +403,9 @@ void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSym
} }
auto spiceGenerator = static_cast<const SPICE_GENERATOR_KIBIS&>( kibisModel->SpiceGenerator() ); auto spiceGenerator = static_cast<const SPICE_GENERATOR_KIBIS&>( kibisModel->SpiceGenerator() );
std::string modelData = spiceGenerator.IbisDevice( aItem ); std::string modelData = spiceGenerator.IbisDevice(
aItem, std::string( m_schematic->Prj().GetProjectPath().c_str() ),
std::string( cacheDir.GetPath( wxPATH_GET_SEPARATOR ) ).c_str() );
cacheFile.Write( wxString( modelData ) ); cacheFile.Write( wxString( modelData ) );
m_rawIncludes.insert( libraryPath ); m_rawIncludes.insert( libraryPath );

View File

@ -303,14 +303,14 @@ std::string IVtable::Spice( int aN, std::string aPort1, std::string aPort2, std:
for( IVtableEntry& entry : m_entries ) for( IVtableEntry& entry : m_entries )
{ {
result += doubleToString( entry.V ); result += doubleToString( entry.V );
result += " "; result += "\n+";
} }
result += "]\n+ y_array=["; result += "]\n+ y_array=[";
for( IVtableEntry& entry : m_entries ) for( IVtableEntry& entry : m_entries )
{ {
result += doubleToString( entry.I.value[aCorner] ); result += doubleToString( entry.I.value[aCorner] );
result += " "; result += "\n+";
} }
result += "]\n+ input_domain=0.05 fraction=TRUE)\n\n"; result += "]\n+ input_domain=0.05 fraction=TRUE)\n\n";
} }
@ -2284,6 +2284,7 @@ bool IbisParser::readDiffPin()
{ {
bool status = true; bool status = true;
m_lineIndex = 0; // rewind
IbisDiffPinEntry entry( m_reporter ); IbisDiffPinEntry entry( m_reporter );
if( m_continue == IBIS_PARSER_CONTINUE::NONE ) // No info on first line if( m_continue == IBIS_PARSER_CONTINUE::NONE ) // No info on first line
@ -2302,7 +2303,7 @@ bool IbisParser::readDiffPin()
Report( _( "Incorrect inv_pin name" ), RPT_SEVERITY_ERROR ); Report( _( "Incorrect inv_pin name" ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( status && readWord( entry.pinB ) ) if( status )
{ {
m_currentComponent->m_diffPin.m_entries.push_back( entry ); m_currentComponent->m_diffPin.m_entries.push_back( entry );
} }
@ -2468,7 +2469,7 @@ bool IbisParser::onNewLine()
return true; return true;
} }
// No new keyword ? Then it is the continuatino of the previous one ! // No new keyword ? Then it is the continuation of the previous one !
switch( m_continue ) switch( m_continue )
{ {
case IBIS_PARSER_CONTINUE::STRING: case IBIS_PARSER_CONTINUE::STRING:

View File

@ -32,6 +32,8 @@
#include "kibis.h" #include "kibis.h"
#include "ibis_parser.h" #include "ibis_parser.h"
#include <sstream> #include <sstream>
#include <sim/spice_simulator.h>
// _() is used here to mark translatable strings in IBIS_REPORTER::Report() // _() is used here to mark translatable strings in IBIS_REPORTER::Report()
// However, currently non ASCII7 chars are nor correctly handled when printing messages // However, currently non ASCII7 chars are nor correctly handled when printing messages
@ -70,11 +72,11 @@ KIBIS::KIBIS( std::string aFileName ) : KIBIS_ANY( this ), m_file( this )
{ {
IBIS_REPORTER reporter; IBIS_REPORTER reporter;
IbisParser parser( &reporter ); IbisParser parser( &reporter );
bool status = true;
parser.m_parrot = false; parser.m_parrot = false;
parser.ParseFile( aFileName ); status &= parser.ParseFile( aFileName );
bool status = true;
status &= m_file.Init( parser ); status &= m_file.Init( parser );
@ -96,6 +98,18 @@ KIBIS::KIBIS( std::string aFileName ) : KIBIS_ANY( this ), m_file( this )
{ {
pin.m_parent = &( m_components.back() ); pin.m_parent = &( m_components.back() );
} }
for( IbisDiffPinEntry dpEntry : iComponent.m_diffPin.m_entries )
{
KIBIS_PIN* pinA = m_components.back().GetPin( dpEntry.pinA );
KIBIS_PIN* pinB = m_components.back().GetPin( dpEntry.pinB );
if( pinA && pinB )
{
pinA->m_complementaryPin = pinB;
pinB->m_complementaryPin = pinA;
}
}
} }
m_valid = status; m_valid = status;
@ -520,7 +534,7 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
simul += std::to_string( i ); simul += std::to_string( i );
simul += " "; simul += " ";
simul += aNode2; simul += aNode2;
simul += " pwl ( "; simul += " pwl ( \n+";
if( i != 0 ) if( i != 0 )
{ {
@ -532,7 +546,7 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
simul += doubleToString( entry0.t + timing - deltaT ); simul += doubleToString( entry0.t + timing - deltaT );
simul += " "; simul += " ";
simul += "0"; simul += "0";
simul += " "; simul += "\n+";
} }
for( VTtableEntry& entry : WF->m_table.m_entries ) for( VTtableEntry& entry : WF->m_table.m_entries )
@ -540,7 +554,7 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
simul += doubleToString( entry.t + timing ); simul += doubleToString( entry.t + timing );
simul += " "; simul += " ";
simul += doubleToString( entry.V.value[supply] - delta ); simul += doubleToString( entry.V.value[supply] - delta );
simul += " "; simul += "\n+";
} }
simul += ")\n"; simul += ")\n";
} }
@ -559,7 +573,7 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
{ {
simul += " v( stimuli"; simul += " v( stimuli";
simul += std::to_string( ii ); simul += std::to_string( ii );
simul += " ) + "; simul += " ) +\n+";
} }
// Depending on the first bit, we add a different DC value // Depending on the first bit, we add a different DC value
@ -632,29 +646,25 @@ std::string KIBIS_PIN::addDie( KIBIS_MODEL& aModel, KIBIS_PARAMETER& aParam, int
void KIBIS_PIN::getKuKdFromFile( std::string* aSimul ) void KIBIS_PIN::getKuKdFromFile( std::string* aSimul )
{ {
// @TODO std::string outputFileName = m_topLevel->m_cacheDir + "temp_output.spice";
// that's not the best way to do, but ¯\_(ツ)_/¯
std::ifstream in( "temp_input.spice" );
if( std::remove( "temp_input.spice" ) ) if( std::remove( outputFileName.c_str() ) )
{
Report( _( "Cannot remove temporary input file" ), RPT_SEVERITY_WARNING );
}
if( std::remove( "temp_ouput.spice" ) )
{ {
Report( _( "Cannot remove temporary output file" ), RPT_SEVERITY_WARNING ); Report( _( "Cannot remove temporary output file" ), RPT_SEVERITY_WARNING );
} }
std::ofstream file( "temp_input.spice" ); std::shared_ptr<SPICE_SIMULATOR> ng = SIMULATOR::CreateInstance( "ng-kibis" );
file << *aSimul;
system( "ngspice temp_input.spice" );
if( !ng )
{
throw std::runtime_error( "Could not create simulator instance" );
return;
}
ng->Init();
ng->LoadNetlist( *aSimul );
std::ifstream KuKdfile; std::ifstream KuKdfile;
KuKdfile.open( "temp_output.spice" ); KuKdfile.open( outputFileName );
std::vector<double> ku, kd, t; std::vector<double> ku, kd, t;
if( KuKdfile ) if( KuKdfile )
@ -700,21 +710,14 @@ void KIBIS_PIN::getKuKdFromFile( std::string* aSimul )
} }
else else
{ {
Report( _( "Error while creating temporary file" ), RPT_SEVERITY_ERROR ); Report( _( "Error while creating temporary output file" ), RPT_SEVERITY_ERROR );
} }
if( std::remove( "temp_input.spice" ) ) if( std::remove( outputFileName.c_str() ) )
{
Report( _( "Cannot remove temporary input file" ), RPT_SEVERITY_WARNING );
}
if( std::remove( "temp_ouput.spice" ) )
{ {
Report( _( "Cannot remove temporary output file" ), RPT_SEVERITY_WARNING ); Report( _( "Cannot remove temporary output file" ), RPT_SEVERITY_WARNING );
} }
// @TODO : this is the end of the dirty code
m_Ku = ku; m_Ku = ku;
m_Kd = kd; m_Kd = kd;
m_t = t; m_t = t;
@ -775,7 +778,6 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
{ {
case KIBIS_WAVEFORM_TYPE::RECTANGULAR: case KIBIS_WAVEFORM_TYPE::RECTANGULAR:
{ {
std::vector<std::pair<int, double>> bits;
KIBIS_WAVEFORM_RECTANGULAR* rectWave = dynamic_cast<KIBIS_WAVEFORM_RECTANGULAR*>( wave ); KIBIS_WAVEFORM_RECTANGULAR* rectWave = dynamic_cast<KIBIS_WAVEFORM_RECTANGULAR*>( wave );
if( !rectWave ) if( !rectWave )
@ -792,26 +794,14 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
Report( _( "Falling edge is longer than off time." ), RPT_SEVERITY_WARNING ); Report( _( "Falling edge is longer than off time." ), RPT_SEVERITY_WARNING );
} }
for( int i = 0; i < rectWave->m_cycles; i++ )
{
std::pair<int, double> bit;
bit.first = rectWave->inverted ? 0 : 1;
bit.second = ( rectWave->m_ton + rectWave->m_toff ) * i + rectWave->m_delay;
bits.push_back( bit );
bit.first = rectWave->inverted ? 1 : 0;
bit.second = ( rectWave->m_ton + rectWave->m_toff ) * i + rectWave->m_delay
+ rectWave->m_ton;
bits.push_back( bit );
}
std::vector<std::pair<int, double>> bits = wave->GenerateBitSequence();
simul += aModel.generateSquareWave( "DIE0", "GND", bits, aPair, aParam ); simul += aModel.generateSquareWave( "DIE0", "GND", bits, aPair, aParam );
break; break;
} }
case KIBIS_WAVEFORM_TYPE::PRBS: case KIBIS_WAVEFORM_TYPE::PRBS:
{ {
KIBIS_WAVEFORM_PRBS* prbsWave = dynamic_cast<KIBIS_WAVEFORM_PRBS*>( wave ); std::vector<std::pair<int, double>> bits = wave->GenerateBitSequence();
std::vector<std::pair<int, double>> bits = prbsWave->GenerateBitSequence();
simul += aModel.generateSquareWave( "DIE0", "GND", bits, aPair, aParam ); simul += aModel.generateSquareWave( "DIE0", "GND", bits, aPair, aParam );
break; break;
} }
@ -939,7 +929,9 @@ void KIBIS_PIN::getKuKdOneWaveform( KIBIS_MODEL& aMod
simul += "run \n"; simul += "run \n";
//simul += "plot v(x1.DIE0) i(VmeasIout) i(VmeasPD) i(VmeasPU) i(VmeasPC) i(VmeasGC)\n"; //simul += "plot v(x1.DIE0) i(VmeasIout) i(VmeasPD) i(VmeasPU) i(VmeasPC) i(VmeasGC)\n";
//simul += "plot v(KU) v(KD)\n"; //simul += "plot v(KU) v(KD)\n";
simul += "write temp_output.spice v(KU) v(KD)\n"; // @TODO we might want to remove this...
std::string outputFileName = m_topLevel->m_cacheDir + "temp_output.spice";
simul += "write " + outputFileName + " v(KU) v(KD)\n";
simul += "quit\n"; simul += "quit\n";
simul += ".endc \n"; simul += ".endc \n";
simul += ".end \n"; simul += ".end \n";
@ -1144,7 +1136,8 @@ void KIBIS_PIN::getKuKdTwoWaveforms( KIBIS_MODEL& aMo
simul += "run \n"; simul += "run \n";
simul += "plot v(KU) v(KD)\n"; simul += "plot v(KU) v(KD)\n";
//simul += "plot v(x1.DIE0) \n"; //simul += "plot v(x1.DIE0) \n";
simul += "write temp_output.spice v(KU) v(KD)\n"; // @TODO we might want to remove this... std::string outputFileName = m_topLevel->m_cacheDir + "temp_output.spice";
simul += "write " + outputFileName + " v(KU) v(KD)\n";
simul += "quit\n"; simul += "quit\n";
simul += ".endc \n"; simul += ".endc \n";
simul += ".end \n"; simul += ".end \n";
@ -1455,6 +1448,51 @@ void KIBIS_PARAMETER::SetCornerFromString( IBIS_CORNER& aCorner, std::string aSt
aCorner = IBIS_CORNER::TYP; aCorner = IBIS_CORNER::TYP;
} }
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_STUCK_HIGH::GenerateBitSequence()
{
std::vector<std::pair<int, double>> bits;
std::pair<int, double> bit;
bit.first = inverted ? 1 : 0;
bit.second = 0;
return bits;
}
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_STUCK_LOW::GenerateBitSequence()
{
std::vector<std::pair<int, double>> bits;
std::pair<int, double> bit;
bit.first = inverted ? 0 : 1;
bit.second = 0;
return bits;
}
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_HIGH_Z::GenerateBitSequence()
{
std::vector<std::pair<int, double>> bits;
return bits;
}
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_RECTANGULAR::GenerateBitSequence()
{
std::vector<std::pair<int, double>> bits;
for( int i = 0; i < m_cycles; i++ )
{
std::pair<int, double> bit;
bit.first = inverted ? 0 : 1;
bit.second = ( m_ton + m_toff ) * i + m_delay;
bits.push_back( bit );
bit.first = inverted ? 1 : 0;
bit.second = ( m_ton + m_toff ) * i + m_delay + m_ton;
bits.push_back( bit );
}
return bits;
}
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_PRBS::GenerateBitSequence() std::vector<std::pair<int, double>> KIBIS_WAVEFORM_PRBS::GenerateBitSequence()
{ {
std::vector<std::pair<int, double>> bitSequence; std::vector<std::pair<int, double>> bitSequence;
@ -1487,5 +1525,4 @@ std::vector<std::pair<int, double>> KIBIS_WAVEFORM_PRBS::GenerateBitSequence()
} while ( ++bits < m_bits ); } while ( ++bits < m_bits );
return bitSequence; return bitSequence;
}
}

View File

@ -68,6 +68,12 @@ public:
bool inverted = false; // Used for differential drivers bool inverted = false; // Used for differential drivers
virtual ~KIBIS_WAVEFORM(){}; virtual ~KIBIS_WAVEFORM(){};
virtual std::vector<std::pair<int, double>> GenerateBitSequence()
{
std::vector<std::pair<int, double>> bits;
return bits;
};
protected: protected:
KIBIS_WAVEFORM_TYPE m_type = KIBIS_WAVEFORM_TYPE::NONE; KIBIS_WAVEFORM_TYPE m_type = KIBIS_WAVEFORM_TYPE::NONE;
}; };
@ -81,6 +87,7 @@ public:
int m_cycles = 1; int m_cycles = 1;
double m_delay = 0; double m_delay = 0;
std::vector<std::pair<int, double>> GenerateBitSequence() override;
double GetDuration() override { return ( m_ton + m_toff ) * m_cycles; }; double GetDuration() override { return ( m_ton + m_toff ) * m_cycles; };
}; };
@ -93,7 +100,7 @@ public:
double m_delay = 0; double m_delay = 0;
double m_bits = 10; double m_bits = 10;
std::vector<std::pair<int, double>> GenerateBitSequence(); std::vector<std::pair<int, double>> GenerateBitSequence() override;
double GetDuration() override { return m_bits / m_bitrate ; }; double GetDuration() override { return m_bits / m_bitrate ; };
}; };
@ -101,18 +108,21 @@ class KIBIS_WAVEFORM_STUCK_HIGH : public KIBIS_WAVEFORM
{ {
public: public:
KIBIS_WAVEFORM_STUCK_HIGH() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::STUCK_HIGH; }; KIBIS_WAVEFORM_STUCK_HIGH() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::STUCK_HIGH; };
std::vector<std::pair<int, double>> GenerateBitSequence() override;
}; };
class KIBIS_WAVEFORM_STUCK_LOW : public KIBIS_WAVEFORM class KIBIS_WAVEFORM_STUCK_LOW : public KIBIS_WAVEFORM
{ {
public: public:
KIBIS_WAVEFORM_STUCK_LOW() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::STUCK_LOW; }; KIBIS_WAVEFORM_STUCK_LOW() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::STUCK_LOW; };
std::vector<std::pair<int, double>> GenerateBitSequence() override;
}; };
class KIBIS_WAVEFORM_HIGH_Z : public KIBIS_WAVEFORM class KIBIS_WAVEFORM_HIGH_Z : public KIBIS_WAVEFORM
{ {
public: public:
KIBIS_WAVEFORM_HIGH_Z() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::HIGH_Z; }; KIBIS_WAVEFORM_HIGH_Z() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::HIGH_Z; };
std::vector<std::pair<int, double>> GenerateBitSequence() override;
}; };
/** Accuracy level. /** Accuracy level.
@ -186,6 +196,9 @@ public:
std::vector<KIBIS_MODEL> m_models; std::vector<KIBIS_MODEL> m_models;
KIBIS_FILE m_file; KIBIS_FILE m_file;
/** @brief Absolute path of the directory that will be used for caching. */
std::string m_cacheDir = "";
/** @brief Return the model with name aName . Nullptr if not found */ /** @brief Return the model with name aName . Nullptr if not found */
KIBIS_MODEL* GetModel( std::string aName ); KIBIS_MODEL* GetModel( std::string aName );
/** @brief Return the component with name aName . Nullptr if not found */ /** @brief Return the component with name aName . Nullptr if not found */
@ -385,6 +398,10 @@ public:
* @param aSimul The simulation to run, multiline spice directives * @param aSimul The simulation to run, multiline spice directives
*/ */
void getKuKdFromFile( std::string* aSimul ); void getKuKdFromFile( std::string* aSimul );
KIBIS_PIN* m_complementaryPin = nullptr;
bool isDiffPin() { return m_complementaryPin != nullptr; };
}; };
class KIBIS_COMPONENT : public KIBIS_ANY class KIBIS_COMPONENT : public KIBIS_ANY

View File

@ -43,9 +43,6 @@ void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath, SIM_MODEL::TYPE
unsigned pinNumber = 2; unsigned pinNumber = 2;
if( aType == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE || aType == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE )
pinNumber = 3;
for( KIBIS_COMPONENT& kcomp : m_kibis.m_components ) for( KIBIS_COMPONENT& kcomp : m_kibis.m_components )
{ {
m_models.push_back( SIM_MODEL::Create( aType, pinNumber ) ); m_models.push_back( SIM_MODEL::Create( aType, pinNumber ) );
@ -72,8 +69,22 @@ bool SIM_LIBRARY_KIBIS::InitModel( SIM_MODEL_KIBIS& aModel, wxString aCompName )
for( KIBIS_PIN& kpin : kcomp.m_pins ) for( KIBIS_PIN& kpin : kcomp.m_pins )
{ {
aModel.m_ibisPins.emplace_back( kpin.m_pinNumber, kpin.m_signalName ); aModel.m_ibisPins.emplace_back( kpin.m_pinNumber, kpin.m_signalName );
if( kpin.isDiffPin() )
m_diffPins.emplace_back( kcomp.m_name, kpin.m_pinNumber );
} }
return true; return true;
} }
return false; return false;
} }
bool SIM_LIBRARY_KIBIS::isPinDiff( const std::string& aComp, const std::string& aPinNumber )
{
for( std::pair<std::string, std::string> aInfo : m_diffPins )
{
if( aInfo.first == aComp && aInfo.second == aPinNumber )
return true;
}
return false;
}

View File

@ -24,7 +24,7 @@
#ifndef SIM_LIBRARY_KIBIS_H #ifndef SIM_LIBRARY_KIBIS_H
#define SIM_LIBRARY_KIBIS_H #define SIM_LIBRARY_KIBIS_H
#include <../../pcbnew/ibis/kibis.h> #include <sim/kibis/kibis.h>
#include <sim/sim_library.h> #include <sim/sim_library.h>
#include <sim/sim_model_kibis.h> #include <sim/sim_model_kibis.h>
@ -35,6 +35,7 @@ class SIM_LIBRARY_KIBIS : public SIM_LIBRARY
public: public:
static constexpr auto PIN_FIELD = "Ibis_Pin"; static constexpr auto PIN_FIELD = "Ibis_Pin";
static constexpr auto MODEL_FIELD = "Ibis_Model"; static constexpr auto MODEL_FIELD = "Ibis_Model";
static constexpr auto DIFF_FIELD = "Ibis_Diff";
// @copydoc SIM_LIBRARY::ReadFile() // @copydoc SIM_LIBRARY::ReadFile()
void ReadFile( const std::string& aFilePath, SIM_MODEL::TYPE aType ); void ReadFile( const std::string& aFilePath, SIM_MODEL::TYPE aType );
@ -47,9 +48,11 @@ public:
void WriteFile( const std::string& aFilePath ) override{}; void WriteFile( const std::string& aFilePath ) override{};
bool InitModel( SIM_MODEL_KIBIS& aModel, wxString aCompName ); bool InitModel( SIM_MODEL_KIBIS& aModel, wxString aCompName );
bool isPinDiff( const std::string& aComp, const std::string& aPinNumber );
protected: protected:
KIBIS m_kibis; KIBIS m_kibis;
std::vector<std::pair<std::string, std::string>> m_diffPins;
}; };
#endif // SIM_LIBRARY_SPICE_H #endif // SIM_LIBRARY_SPICE_H

View File

@ -36,6 +36,8 @@
#include <sim/sim_model_tline.h> #include <sim/sim_model_tline.h>
#include <sim/sim_model_xspice.h> #include <sim/sim_model_xspice.h>
#include <sim/sim_library_kibis.h>
#include <lib_symbol.h> #include <lib_symbol.h>
#include <confirm.h> #include <confirm.h>
@ -238,8 +240,6 @@ SIM_MODEL::INFO SIM_MODEL::TypeInfo( TYPE aType )
case TYPE::KIBIS_DRIVER_DC: return { DEVICE_TYPE_::KIBIS, "IBISDRIVERDC", "DC driver" }; case TYPE::KIBIS_DRIVER_DC: return { DEVICE_TYPE_::KIBIS, "IBISDRIVERDC", "DC driver" };
case TYPE::KIBIS_DRIVER_RECT: return { DEVICE_TYPE_::KIBIS, "IBISDRIVERRECT", "Rectangular wave driver" }; case TYPE::KIBIS_DRIVER_RECT: return { DEVICE_TYPE_::KIBIS, "IBISDRIVERRECT", "Rectangular wave driver" };
case TYPE::KIBIS_DRIVER_PRBS: return { DEVICE_TYPE_::KIBIS, "IBISDRIVERPRBS", "PRBS driver" }; case TYPE::KIBIS_DRIVER_PRBS: return { DEVICE_TYPE_::KIBIS, "IBISDRIVERPRBS", "PRBS driver" };
case TYPE::KIBIS_DIFFDEVICE: return { DEVICE_TYPE_::KIBIS, "IBISDIFFDEVICE", "Differential device" };
case TYPE::KIBIS_DIFFDRIVER: return { DEVICE_TYPE_::KIBIS, "IBISDIFFDRIVER", "Differential driver" };
case TYPE::RAWSPICE: return { DEVICE_TYPE_::SPICE, "", "" }; case TYPE::RAWSPICE: return { DEVICE_TYPE_::SPICE, "", "" };
@ -376,8 +376,6 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType )
case TYPE::KIBIS_DRIVER_DC: return { "X" }; case TYPE::KIBIS_DRIVER_DC: return { "X" };
case TYPE::KIBIS_DRIVER_RECT: return { "X" }; case TYPE::KIBIS_DRIVER_RECT: return { "X" };
case TYPE::KIBIS_DRIVER_PRBS: return { "X" }; case TYPE::KIBIS_DRIVER_PRBS: return { "X" };
case TYPE::KIBIS_DIFFDEVICE: return { "X" };
case TYPE::KIBIS_DIFFDRIVER: return { "X" };
case TYPE::NONE: case TYPE::NONE:
case TYPE::RAWSPICE: case TYPE::RAWSPICE:
@ -709,6 +707,11 @@ void SIM_MODEL::AddPin( const PIN& aPin )
m_pins.push_back( aPin ); m_pins.push_back( aPin );
} }
void SIM_MODEL::DeletePins()
{
m_pins.clear();
}
int SIM_MODEL::FindModelPinIndex( const std::string& aSymbolPinNumber ) int SIM_MODEL::FindModelPinIndex( const std::string& aSymbolPinNumber )
{ {
@ -949,8 +952,6 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType )
case TYPE::KIBIS_DRIVER_DC: case TYPE::KIBIS_DRIVER_DC:
case TYPE::KIBIS_DRIVER_RECT: case TYPE::KIBIS_DRIVER_RECT:
case TYPE::KIBIS_DRIVER_PRBS: case TYPE::KIBIS_DRIVER_PRBS:
case TYPE::KIBIS_DIFFDEVICE:
case TYPE::KIBIS_DIFFDRIVER:
return std::make_unique<SIM_MODEL_KIBIS>( aType ); return std::make_unique<SIM_MODEL_KIBIS>( aType );
case TYPE::RAWSPICE: case TYPE::RAWSPICE:

View File

@ -347,8 +347,6 @@ public:
KIBIS_DRIVER_DC, KIBIS_DRIVER_DC,
KIBIS_DRIVER_RECT, KIBIS_DRIVER_RECT,
KIBIS_DRIVER_PRBS, KIBIS_DRIVER_PRBS,
KIBIS_DIFFDEVICE,
KIBIS_DIFFDRIVER,
RAWSPICE RAWSPICE
) )
@ -545,6 +543,8 @@ public:
SPICE_INFO GetSpiceInfo() const { return SpiceInfo( GetType() ); } SPICE_INFO GetSpiceInfo() const { return SpiceInfo( GetType() ); }
void AddPin( const PIN& aPin ); void AddPin( const PIN& aPin );
void DeletePins();
int FindModelPinIndex( const std::string& aSymbolPinNumber ); int FindModelPinIndex( const std::string& aSymbolPinNumber );
void AddParam( const PARAM::INFO& aInfo, bool aIsOtherVariant = false ); void AddParam( const PARAM::INFO& aInfo, bool aIsOtherVariant = false );

View File

@ -21,12 +21,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <../../pcbnew/ibis/kibis.h> #include <sim/kibis/kibis.h>
#include <sim/sim_model_kibis.h> #include <sim/sim_model_kibis.h>
#include <sim/sim_library_kibis.h> #include <sim/sim_library_kibis.h>
#include <paths.h> #include <paths.h>
#include <fmt/core.h> #include <fmt/core.h>
#include <wx/filename.h>
#include <kiway.h>
std::string SPICE_GENERATOR_KIBIS::ModelName( const SPICE_ITEM& aItem ) const std::string SPICE_GENERATOR_KIBIS::ModelName( const SPICE_ITEM& aItem ) const
{ {
@ -57,14 +58,29 @@ std::vector<std::string> SPICE_GENERATOR_KIBIS::CurrentNames( const SPICE_ITEM&
} }
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem ) const std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const std::string aCwd,
const std::string aCacheDir ) const
{ {
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::LIBRARY_FIELD ); std::string ibisLibFilename = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::LIBRARY_FIELD );
std::string ibisCompName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::NAME_FIELD ); std::string ibisCompName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::NAME_FIELD );
std::string ibisPinName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::PIN_FIELD ); std::string ibisPinName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::PIN_FIELD );
std::string ibisModelName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::MODEL_FIELD ); std::string ibisModelName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::MODEL_FIELD );
bool diffMode = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
wxFileName libPath = wxFileName( wxString( ibisLibFilename ) );
if( !libPath.IsAbsolute() )
libPath.MakeAbsolute( aCwd );
KIBIS kibis( std::string( libPath.GetAbsolutePath().c_str() ) );
kibis.m_cacheDir = aCacheDir;
if( !kibis.m_valid )
{
THROW_IO_ERROR( wxString::Format( _( "Invalid IBIS file '%s'" ),
ibisLibFilename ) );
}
KIBIS kibis( ibisLibFilename );
KIBIS_COMPONENT* kcomp = kibis.GetComponent( std::string( ibisCompName ) ); KIBIS_COMPONENT* kcomp = kibis.GetComponent( std::string( ibisCompName ) );
if( !kcomp ) if( !kcomp )
@ -72,6 +88,13 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem ) const
KIBIS_PIN* kpin = kcomp->GetPin( ibisPinName ); KIBIS_PIN* kpin = kcomp->GetPin( ibisPinName );
if( !kcomp->m_valid )
{
THROW_IO_ERROR( wxString::Format( _( "Invalid IBIS component '%s'" ),
ibisCompName ) );
}
if( !kpin ) if( !kpin )
{ {
THROW_IO_ERROR( wxString::Format( _( "Could not find IBIS pin '%s' in component '%s'" ), THROW_IO_ERROR( wxString::Format( _( "Could not find IBIS pin '%s' in component '%s'" ),
@ -107,7 +130,10 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem ) const
switch( m_model.GetType() ) switch( m_model.GetType() )
{ {
case SIM_MODEL::TYPE::KIBIS_DEVICE: case SIM_MODEL::TYPE::KIBIS_DEVICE:
kpin->writeSpiceDevice( &result, aItem.modelName, *kmodel, kparams ); if( diffMode )
kpin->writeSpiceDiffDevice( &result, aItem.modelName, *kmodel, kparams );
else
kpin->writeSpiceDevice( &result, aItem.modelName, *kmodel, kparams );
break; break;
case SIM_MODEL::TYPE::KIBIS_DRIVER_DC: case SIM_MODEL::TYPE::KIBIS_DRIVER_DC:
@ -130,7 +156,10 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem ) const
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_HIGH() ); static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_HIGH() );
} }
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams ); if( diffMode )
kpin->writeSpiceDiffDriver( &result, aItem.modelName, *kmodel, kparams );
else
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
break; break;
} }
@ -138,12 +167,24 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem ) const
{ {
KIBIS_WAVEFORM_RECTANGULAR* waveform = new KIBIS_WAVEFORM_RECTANGULAR(); KIBIS_WAVEFORM_RECTANGULAR* waveform = new KIBIS_WAVEFORM_RECTANGULAR();
waveform->m_ton = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "ton" )->value ).Get().value_or( 1 ); if ( m_model.FindParam( "ton" ) )
waveform->m_toff = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "toff" )->value ).Get().value_or( 1 ); waveform->m_ton = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "ton" )->value ).Get().value_or( 1 );
waveform->m_delay = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "delay" )->value ).Get().value_or( 0 );
if ( m_model.FindParam( "toff" ) )
waveform->m_toff = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "toff" )->value ).Get().value_or( 1 );
if ( m_model.FindParam( "delay" ) )
waveform->m_delay = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "delay" )->value ).Get().value_or( 0 );
if ( m_model.FindParam( "cycles" ) )
waveform->m_cycles = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "cycles" )->value ).Get().value_or( 0 );
kparams.m_waveform = waveform; kparams.m_waveform = waveform;
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
if( diffMode )
kpin->writeSpiceDiffDriver( &result, aItem.modelName, *kmodel, kparams );
else
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
break; break;
} }
@ -151,12 +192,21 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem ) const
{ {
KIBIS_WAVEFORM_PRBS* waveform = new KIBIS_WAVEFORM_PRBS(); KIBIS_WAVEFORM_PRBS* waveform = new KIBIS_WAVEFORM_PRBS();
waveform->m_bitrate = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "f0" )->value ).Get().value_or( 0 ); if ( m_model.FindParam( "f0" ) )
waveform->m_bitrate = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "f0" )->value ).Get().value_or( 0 );
if ( m_model.FindParam( "bits" ) )
waveform->m_bits = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "bits" )->value ).Get().value_or( 0 ); waveform->m_bits = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "bits" )->value ).Get().value_or( 0 );
if ( m_model.FindParam( "delay" ) )
waveform->m_delay = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "delay" )->value ).Get().value_or( 0 ); waveform->m_delay = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "delay" )->value ).Get().value_or( 0 );
kparams.m_waveform = waveform; kparams.m_waveform = waveform;
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
if( diffMode )
kpin->writeSpiceDiffDriver( &result, aItem.modelName, *kmodel, kparams );
else
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
break; break;
} }
@ -195,7 +245,15 @@ SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType ) :
for( const PARAM::INFO& paramInfo : *paramInfos ) for( const PARAM::INFO& paramInfo : *paramInfos )
AddParam( paramInfo ); AddParam( paramInfo );
if( aType == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE || aType == SIM_MODEL::TYPE::KIBIS_DIFFDRIVER ) SwitchSingleEndedDiff( false );
}
void SIM_MODEL_KIBIS::SwitchSingleEndedDiff( bool aDiff )
{
DeletePins();
if( aDiff )
{ {
AddPin( { "GND", "1" } ); AddPin( { "GND", "1" } );
AddPin( { "+", "2" } ); AddPin( { "+", "2" } );
@ -208,7 +266,6 @@ SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType ) :
} }
} }
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource ) : SIM_MODEL_KIBIS( aType ) SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource ) : SIM_MODEL_KIBIS( aType )
{ {
for( PARAM& param1 : m_params ) for( PARAM& param1 : m_params )
@ -405,7 +462,15 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_KIBIS::makeRectWaveformParamInfos(
paramInfo.defaultValue = "0"; paramInfo.defaultValue = "0";
paramInfo.description = _( "Delay" ); paramInfo.description = _( "Delay" );
paramInfos.push_back( paramInfo ); paramInfos.push_back( paramInfo );
paramInfo.name = "cycles";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "1";
paramInfo.description = _( "cycles" );
paramInfos.push_back( paramInfo );
return paramInfos; return paramInfos;
} }
@ -433,3 +498,20 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_KIBIS::makePrbsWaveformParamInfos(
return paramInfos; return paramInfos;
} }
void SIM_MODEL_KIBIS::ReadDataSchFields( unsigned aSymbolPinCount, const std::vector<SCH_FIELD>* aFields )
{
bool diffMode = SIM_MODEL::GetFieldValue( aFields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
SwitchSingleEndedDiff( diffMode );
SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields );
}
void SIM_MODEL_KIBIS::ReadDataLibFields( unsigned aSymbolPinCount, const std::vector<LIB_FIELD>* aFields )
{
bool diffMode = SIM_MODEL::GetFieldValue( aFields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
SwitchSingleEndedDiff( diffMode );
SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields );
}

View File

@ -24,7 +24,7 @@
#ifndef SIM_MODEL_KIBIS_H #ifndef SIM_MODEL_KIBIS_H
#define SIM_MODEL_KIBIS_H #define SIM_MODEL_KIBIS_H
#include <../../pcbnew/ibis/kibis.h> #include <sim/kibis/kibis.h>
#include <sim/sim_model.h> #include <sim/sim_model.h>
#include <sim/spice_generator.h> #include <sim/spice_generator.h>
#include <project.h> #include <project.h>
@ -41,7 +41,8 @@ public:
std::string ModelLine( const SPICE_ITEM& aItem ) const override; std::string ModelLine( const SPICE_ITEM& aItem ) const override;
std::vector<std::string> CurrentNames( const SPICE_ITEM& aItem ) const override; std::vector<std::string> CurrentNames( const SPICE_ITEM& aItem ) const override;
std::string IbisDevice( const SPICE_ITEM& aItem ) const; std::string IbisDevice( const SPICE_ITEM& aItem, const std::string aCwd,
const std::string aCacheDir ) const;
protected: protected:
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> GetInstanceParams() const override; std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> GetInstanceParams() const override;
@ -88,6 +89,13 @@ public:
void SetBaseModel( const SIM_MODEL& aBaseModel ) override; void SetBaseModel( const SIM_MODEL& aBaseModel ) override;
void SwitchSingleEndedDiff( bool aDiff );
bool CanDifferential() { return m_enableDiff; };
bool m_enableDiff;
void ReadDataSchFields( unsigned aSymbolPinCount, const std::vector<SCH_FIELD>* aFields ) override;
void ReadDataLibFields( unsigned aSymbolPinCount, const std::vector<LIB_FIELD>* aFields ) override;
protected: protected:
void CreatePins( unsigned aSymbolPinCount ) override; void CreatePins( unsigned aSymbolPinCount ) override;

View File

@ -49,5 +49,5 @@ add_subdirectory( unittests )
add_subdirectory( tools ) add_subdirectory( tools )
if( KICAD_SIGNAL_INTEGRITY ) if( KICAD_SIGNAL_INTEGRITY )
add_subdirectory( ibis ) #add_subdirectory( ibis )
endif() endif()

View File

@ -25,40 +25,32 @@ find_package(Boost COMPONENTS unit_test_framework REQUIRED)
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED ) find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
add_definitions(-DBOOST_TEST_DYN_LINK -DPCBNEW -DDRC_PROTO -DTEST_APP_NO_MAIN) add_definitions(-DBOOST_TEST_DYN_LINK -DEESCHEMA -DDRC_PROTO -DTEST_APP_NO_MAIN)
add_executable( ibis_proto add_executable( ibis_proto
qaIbisParser.cpp qaIbisParser.cpp
${CMAKE_SOURCE_DIR}/pcbnew/ibis/ibis_parser.cpp ${CMAKE_SOURCE_DIR}/eeschema/sim/kibis/ibis_parser.cpp
${CMAKE_SOURCE_DIR}/pcbnew/ibis/kibis.cpp ${CMAKE_SOURCE_DIR}/eeschema/sim/kibis/kibis.cpp
${CMAKE_SOURCE_DIR}/eeschema/sim/ngspice_helpers.cpp
${CMAKE_SOURCE_DIR}/eeschema/sim/ngspice.cpp
) )
add_dependencies( ibis_proto pnsrouter pcbcommon ${PCBNEW_IO_LIBRARIES} ) add_dependencies( ibis_proto pnsrouter pcbcommon )
include_directories( BEFORE ${INC_BEFORE} ) include_directories( BEFORE ${INC_BEFORE} )
include_directories( include_directories(
${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/3d-viewer
${CMAKE_SOURCE_DIR}/common ${CMAKE_SOURCE_DIR}/common
${CMAKE_SOURCE_DIR}/pcbnew ${CMAKE_SOURCE_DIR}/eeschema
${CMAKE_SOURCE_DIR}/pcbnew/router ${CMAKE_SOURCE_DIR}/eeschema/sim
${CMAKE_SOURCE_DIR}/pcbnew/tools ${CMAKE_SOURCE_DIR}/qa/eeschema_utils/include
${CMAKE_SOURCE_DIR}/pcbnew/dialogs
${CMAKE_SOURCE_DIR}/polygon
${CMAKE_SOURCE_DIR}/common/geometry
${CMAKE_SOURCE_DIR}/libs/kimath/include/math
${CMAKE_SOURCE_DIR}/qa/common
${CMAKE_SOURCE_DIR}/qa
${CMAKE_SOURCE_DIR}/qa/qa_utils
${CMAKE_SOURCE_DIR}/qa/qa_utils/include
${CMAKE_SOURCE_DIR}/qa/pcbnew_utils/include
${Boost_INCLUDE_DIR} ${Boost_INCLUDE_DIR}
${INC_AFTER} ${INC_AFTER}
) )
target_link_libraries( ibis_proto target_link_libraries( ibis_proto
qa_pcbnew_utils qa_eechema_utils
3d-viewer 3d-viewer
connectivity connectivity
pcbcommon pcbcommon
@ -71,12 +63,11 @@ target_link_libraries( ibis_proto
tinyspline_lib tinyspline_lib
nanosvg nanosvg
idf3 idf3
${PCBNEW_IO_LIBRARIES}
${wxWidgets_LIBRARIES} ${wxWidgets_LIBRARIES}
${GDI_PLUS_LIBRARIES} ${GDI_PLUS_LIBRARIES}
${PYTHON_LIBRARIES} ${PYTHON_LIBRARIES}
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${PCBNEW_EXTRA_LIBS} # -lrt must follow Boost ${EESCHEMA_EXTRA_LIBS} # -lrt must follow Boost
) )
configure_file( "ibis_v1_1.ibs" "ibis_v1_1.ibs" COPYONLY ) configure_file( "ibis_v1_1.ibs" "ibis_v1_1.ibs" COPYONLY )

View File

@ -1,4 +1,4 @@
#include "../../pcbnew/ibis/kibis.h" #include "../../eeschema/sim/kibis/kibis.h"
#include <wx/textfile.h> #include <wx/textfile.h>
int main( void ) int main( void )