Allow mapping sim model pins to arbitrary string symbol pin numbers
This change removes the incorrect assumption that symbol pin numbers are integers and are the same as indexes in the vector storing the symbol pins. "~" is now used to denote a floating sim model pin.
This commit is contained in:
parent
73cfea892c
commit
6fad25f8ed
|
@ -51,7 +51,7 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
|
||||||
|
|
||||||
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.GetLibPins().size() ) );
|
||||||
|
|
||||||
SIM_MODEL::DEVICE_TYPE_ deviceType = SIM_MODEL::TypeInfo( type ).deviceType;
|
SIM_MODEL::DEVICE_TYPE_ deviceType = SIM_MODEL::TypeInfo( type ).deviceType;
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ bool DIALOG_SIM_MODEL<T>::TransferDataToWindow()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_models.at( static_cast<int>( SIM_MODEL::ReadTypeFromFields( m_fields ) ) )
|
m_models.at( static_cast<int>( SIM_MODEL::ReadTypeFromFields( m_fields ) ) )
|
||||||
= SIM_MODEL::Create( m_symbol.GetAllPins().size(), m_fields );
|
= SIM_MODEL::Create( m_symbol.GetLibPins().size(), m_fields );
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
|
@ -266,7 +266,7 @@ void DIALOG_SIM_MODEL<T>::updateModelParamsTab()
|
||||||
|
|
||||||
m_paramGrid->CollapseAll();
|
m_paramGrid->CollapseAll();
|
||||||
|
|
||||||
for( unsigned i = 0; i < curModel().GetParamCount(); ++i )
|
for( int i = 0; i < curModel().GetParamCount(); ++i )
|
||||||
addParamPropertyIfRelevant( i );
|
addParamPropertyIfRelevant( i );
|
||||||
|
|
||||||
m_paramGrid->CollapseAll();
|
m_paramGrid->CollapseAll();
|
||||||
|
@ -285,10 +285,10 @@ void DIALOG_SIM_MODEL<T>::updateModelParamsTab()
|
||||||
wxColour bgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetBgCol();
|
wxColour bgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetBgCol();
|
||||||
wxColour fgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetFgCol();
|
wxColour fgCol = m_paramGrid->GetGrid()->GetPropertyDefaultCell().GetFgCol();
|
||||||
|
|
||||||
for( int i = 0; i < m_paramGridMgr->GetColumnCount(); ++i )
|
for( int col = 0; col < m_paramGridMgr->GetColumnCount(); ++col )
|
||||||
{
|
{
|
||||||
prop->GetCell( i ).SetBgCol( bgCol );
|
prop->GetCell( col ).SetBgCol( bgCol );
|
||||||
prop->GetCell( i ).SetFgCol( fgCol );
|
prop->GetCell( col ).SetFgCol( fgCol );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Model values other than the currently edited value may have changed. Update them.
|
// Model values other than the currently edited value may have changed. Update them.
|
||||||
|
@ -329,38 +329,36 @@ void DIALOG_SIM_MODEL<T>::updatePinAssignmentsTab()
|
||||||
// First reset the grid.
|
// First reset the grid.
|
||||||
|
|
||||||
m_pinAssignmentsGrid->ClearRows();
|
m_pinAssignmentsGrid->ClearRows();
|
||||||
std::vector<SCH_PIN*> pinList = m_symbol.GetAllPins();
|
m_pinAssignmentsGrid->AppendRows( static_cast<int>( m_symbol.GetLibPins().size() ) );
|
||||||
|
|
||||||
m_pinAssignmentsGrid->AppendRows( static_cast<int>( pinList.size() ) );
|
for( int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row )
|
||||||
|
|
||||||
for( int i = 0; i < m_pinAssignmentsGrid->GetNumberRows(); ++i )
|
|
||||||
{
|
{
|
||||||
m_pinAssignmentsGrid->SetCellValue( i, static_cast<int>( PIN_COLUMN::MODEL ),
|
m_pinAssignmentsGrid->SetCellValue( row, static_cast<int>( PIN_COLUMN::MODEL ),
|
||||||
"Not Connected" );
|
"Not Connected" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now set the grid values.
|
// Now set up the grid values in the Model column.
|
||||||
for( unsigned i = 0; i < curModel().GetPinCount(); ++i )
|
for( int modelPinIndex = 0; modelPinIndex < curModel().GetPinCount(); ++modelPinIndex )
|
||||||
{
|
{
|
||||||
unsigned symbolPinNumber = curModel().GetPin( i ).symbolPinNumber;
|
wxString symbolPinNumber = curModel().GetPin( modelPinIndex ).symbolPinNumber;
|
||||||
|
|
||||||
if( symbolPinNumber == SIM_MODEL::PIN::NOT_CONNECTED )
|
if( symbolPinNumber == "" )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wxString modelPinString = getModelPinString( i + 1 );
|
wxString modelPinString = getModelPinString( modelPinIndex );
|
||||||
wxArrayString choices;
|
wxArrayString choices;
|
||||||
|
|
||||||
m_pinAssignmentsGrid->SetCellValue( static_cast<int>( symbolPinNumber - 1 ),
|
m_pinAssignmentsGrid->SetCellValue( findSymbolPinRow( symbolPinNumber ),
|
||||||
static_cast<int>( PIN_COLUMN::MODEL ),
|
static_cast<int>( PIN_COLUMN::MODEL ),
|
||||||
modelPinString );
|
modelPinString );
|
||||||
}
|
}
|
||||||
|
|
||||||
wxArrayString modelPinChoices = getModelPinChoices();
|
wxArrayString modelPinChoices = getModelPinChoices();
|
||||||
|
|
||||||
// Now set up cell editors, including dropdown options.
|
// Set up the Symbol column grid values and Model column cell editors with dropdown options.
|
||||||
for( int i = 0; i < m_pinAssignmentsGrid->GetNumberRows(); ++i )
|
for( int i = 0; i < m_pinAssignmentsGrid->GetNumberRows(); ++i )
|
||||||
{
|
{
|
||||||
wxString symbolPinString = getSymbolPinString( i + 1 );
|
wxString symbolPinString = getSymbolPinString( i );
|
||||||
|
|
||||||
m_pinAssignmentsGrid->SetReadOnly( i, static_cast<int>( PIN_COLUMN::SYMBOL ) );
|
m_pinAssignmentsGrid->SetReadOnly( i, static_cast<int>( PIN_COLUMN::SYMBOL ) );
|
||||||
m_pinAssignmentsGrid->SetCellValue( i, static_cast<int>( PIN_COLUMN::SYMBOL ),
|
m_pinAssignmentsGrid->SetCellValue( i, static_cast<int>( PIN_COLUMN::SYMBOL ),
|
||||||
|
@ -421,12 +419,12 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aFilePath )
|
||||||
//TODO: it's not cur model.
|
//TODO: it's not cur model.
|
||||||
|
|
||||||
m_libraryModels.push_back(
|
m_libraryModels.push_back(
|
||||||
SIM_MODEL::Create( baseModel, m_symbol.GetAllPins().size(), m_fields ) );
|
SIM_MODEL::Create( baseModel, m_symbol.GetLibPins().size(), m_fields ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_libraryModels.push_back(
|
m_libraryModels.push_back(
|
||||||
SIM_MODEL::Create( baseModel, m_symbol.GetAllPins().size() ) );
|
SIM_MODEL::Create( baseModel, m_symbol.GetLibPins().size() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -600,6 +598,21 @@ wxPGProperty* DIALOG_SIM_MODEL<T>::newParamProperty( int aParamIndex ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int DIALOG_SIM_MODEL<T>::findSymbolPinRow( const wxString& aSymbolPinNumber ) const
|
||||||
|
{
|
||||||
|
for( int row = 0; row < static_cast<int>( m_symbol.GetLibPins().size() ); ++row )
|
||||||
|
{
|
||||||
|
LIB_PIN* pin = m_symbol.GetLibPins()[row];
|
||||||
|
|
||||||
|
if( pin->GetNumber() == aSymbolPinNumber )
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SIM_MODEL& DIALOG_SIM_MODEL<T>::curModel() const
|
SIM_MODEL& DIALOG_SIM_MODEL<T>::curModel() const
|
||||||
{
|
{
|
||||||
|
@ -621,35 +634,43 @@ std::shared_ptr<SIM_MODEL> DIALOG_SIM_MODEL<T>::curModelSharedPtr() const
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
wxString DIALOG_SIM_MODEL<T>::getSymbolPinString( int symbolPinNumber ) const
|
wxString DIALOG_SIM_MODEL<T>::getSymbolPinString( int symbolPinIndex ) const
|
||||||
{
|
{
|
||||||
wxString name = "";
|
LIB_PIN* pin = m_symbol.GetLibPins().at( symbolPinIndex );
|
||||||
SCH_PIN* symbolPin = m_symbol.GetAllPins().at( symbolPinNumber - 1 );
|
wxString number;
|
||||||
|
wxString name;
|
||||||
|
|
||||||
if( symbolPin )
|
if( pin )
|
||||||
name = symbolPin->GetShownName();
|
{
|
||||||
|
number = pin->GetShownNumber();
|
||||||
|
name = pin->GetShownName();
|
||||||
|
}
|
||||||
|
|
||||||
if( name.IsEmpty() )
|
LOCALE_IO toggle;
|
||||||
return wxString::Format( "%d", symbolPinNumber );
|
|
||||||
|
if( name == "" )
|
||||||
|
return wxString::Format( "%s", number );
|
||||||
else
|
else
|
||||||
return wxString::Format( "%d (%s)", symbolPinNumber, name );
|
return wxString::Format( "%s (%s)", number, name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
wxString DIALOG_SIM_MODEL<T>::getModelPinString( int modelPinNumber ) const
|
wxString DIALOG_SIM_MODEL<T>::getModelPinString( int aModelPinIndex ) const
|
||||||
{
|
{
|
||||||
const wxString& pinName = curModel().GetPin( modelPinNumber - 1 ).name;
|
const wxString& pinName = curModel().GetPin( aModelPinIndex ).name;
|
||||||
|
|
||||||
if( pinName.IsEmpty() )
|
LOCALE_IO toggle;
|
||||||
return wxString::Format( "%d", modelPinNumber, pinName );
|
|
||||||
|
if( pinName == "" )
|
||||||
|
return wxString::Format( "%d", aModelPinIndex + 1, pinName );
|
||||||
else
|
else
|
||||||
return wxString::Format( "%d (%s)", modelPinNumber, pinName );
|
return wxString::Format( "%d (%s)", aModelPinIndex + 1, pinName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
unsigned DIALOG_SIM_MODEL<T>::getModelPinNumber( const wxString& aModelPinString ) const
|
int DIALOG_SIM_MODEL<T>::getModelPinIndex( const wxString& aModelPinString ) const
|
||||||
{
|
{
|
||||||
if( aModelPinString == "Not Connected" )
|
if( aModelPinString == "Not Connected" )
|
||||||
return SIM_MODEL::PIN::NOT_CONNECTED;
|
return SIM_MODEL::PIN::NOT_CONNECTED;
|
||||||
|
@ -662,7 +683,7 @@ unsigned DIALOG_SIM_MODEL<T>::getModelPinNumber( const wxString& aModelPinString
|
||||||
long result = 0;
|
long result = 0;
|
||||||
aModelPinString.Mid( 0, length ).ToCLong( &result );
|
aModelPinString.Mid( 0, length ).ToCLong( &result );
|
||||||
|
|
||||||
return static_cast<unsigned>( result );
|
return static_cast<int>( result - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -672,21 +693,20 @@ wxArrayString DIALOG_SIM_MODEL<T>::getModelPinChoices() const
|
||||||
wxArrayString modelPinChoices;
|
wxArrayString modelPinChoices;
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
|
|
||||||
for( unsigned i = 0; i < curModel().GetPinCount(); ++i )
|
for( int i = 0; i < curModel().GetPinCount(); ++i )
|
||||||
{
|
{
|
||||||
const SIM_MODEL::PIN& modelPin = curModel().GetPin( i );
|
const SIM_MODEL::PIN& modelPin = curModel().GetPin( i );
|
||||||
int modelPinNumber = static_cast<int>( i + 1 );
|
|
||||||
|
|
||||||
if( modelPin.symbolPinNumber != SIM_MODEL::PIN::NOT_CONNECTED )
|
if( modelPin.symbolPinNumber != "" )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( isFirst )
|
if( isFirst )
|
||||||
{
|
{
|
||||||
modelPinChoices.Add( getModelPinString( modelPinNumber ) );
|
modelPinChoices.Add( getModelPinString( i ) );
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
modelPinChoices.Add( getModelPinString( modelPinNumber ) );
|
modelPinChoices.Add( getModelPinString( i ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
modelPinChoices.Add( "Not Connected" );
|
modelPinChoices.Add( "Not Connected" );
|
||||||
|
@ -806,16 +826,19 @@ void DIALOG_SIM_MODEL<T>::onCodePreviewSetFocus( wxFocusEvent& aEvent )
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void DIALOG_SIM_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent )
|
void DIALOG_SIM_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent )
|
||||||
{
|
{
|
||||||
int symbolPinNumber = aEvent.GetRow() + 1;
|
int symbolPinIndex = aEvent.GetRow();
|
||||||
unsigned oldModelPinNumber = getModelPinNumber( aEvent.GetString() );
|
int oldModelPinIndex = getModelPinIndex( aEvent.GetString() );
|
||||||
unsigned modelPinNumber = getModelPinNumber(
|
int modelPinIndex = getModelPinIndex(
|
||||||
m_pinAssignmentsGrid->GetCellValue( aEvent.GetRow(), aEvent.GetCol() ) );
|
m_pinAssignmentsGrid->GetCellValue( aEvent.GetRow(), aEvent.GetCol() ) );
|
||||||
|
|
||||||
if( oldModelPinNumber != SIM_MODEL::PIN::NOT_CONNECTED )
|
if( oldModelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED )
|
||||||
curModel().SetPinSymbolPinNumber( oldModelPinNumber - 1, SIM_MODEL::PIN::NOT_CONNECTED );
|
curModel().SetPinSymbolPinNumber( oldModelPinIndex, "" );
|
||||||
|
|
||||||
if( modelPinNumber != SIM_MODEL::PIN::NOT_CONNECTED )
|
if( modelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED )
|
||||||
curModel().SetPinSymbolPinNumber( modelPinNumber - 1, symbolPinNumber );
|
{
|
||||||
|
curModel().SetPinSymbolPinNumber( modelPinIndex,
|
||||||
|
m_symbol.GetLibPins().at( symbolPinIndex )->GetShownNumber() );
|
||||||
|
}
|
||||||
|
|
||||||
updatePinAssignmentsTab();
|
updatePinAssignmentsTab();
|
||||||
|
|
||||||
|
|
|
@ -85,12 +85,14 @@ private:
|
||||||
void addParamPropertyIfRelevant( int aParamIndex );
|
void addParamPropertyIfRelevant( int aParamIndex );
|
||||||
wxPGProperty* newParamProperty( int aParamIndex ) const;
|
wxPGProperty* newParamProperty( int aParamIndex ) const;
|
||||||
|
|
||||||
|
int findSymbolPinRow( const wxString& aSymbolPinNumber ) const;
|
||||||
|
|
||||||
SIM_MODEL& curModel() const;
|
SIM_MODEL& curModel() const;
|
||||||
std::shared_ptr<SIM_MODEL> curModelSharedPtr() const;
|
std::shared_ptr<SIM_MODEL> curModelSharedPtr() const;
|
||||||
|
|
||||||
wxString getSymbolPinString( int aSymbolPinNumber ) const;
|
wxString getSymbolPinString( int aSymbolPinNumber ) const;
|
||||||
wxString getModelPinString( int aModelPinNumber ) const;
|
wxString getModelPinString( int aModelPinIndex ) const;
|
||||||
unsigned getModelPinNumber( const wxString& aModelPinString ) const;
|
int getModelPinIndex( const wxString& aModelPinString ) const;
|
||||||
wxArrayString getModelPinChoices() const;
|
wxArrayString getModelPinChoices() const;
|
||||||
|
|
||||||
void onRadioButton( wxCommandEvent& aEvent ) override;
|
void onRadioButton( wxCommandEvent& aEvent ) override;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <string_utils.h>
|
#include <string_utils.h>
|
||||||
#include <pegtl.hpp>
|
#include <pegtl.hpp>
|
||||||
#include <pegtl/contrib/parse_tree.hpp>
|
#include <pegtl/contrib/parse_tree.hpp>
|
||||||
|
#include <locale_io.h>
|
||||||
|
|
||||||
|
|
||||||
namespace NETLIST_EXPORTER_SPICE_PARSER
|
namespace NETLIST_EXPORTER_SPICE_PARSER
|
||||||
|
@ -94,7 +95,7 @@ bool NETLIST_EXPORTER_SPICE::GenerateNetlist( OUTPUTFORMATTER& aFormatter, unsig
|
||||||
bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions )
|
bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions )
|
||||||
{
|
{
|
||||||
std::set<wxString> refNames; // Set of reference names to check for duplication.
|
std::set<wxString> refNames; // Set of reference names to check for duplication.
|
||||||
int notConnectedCounter = 1;
|
int NCCounter = 1;
|
||||||
|
|
||||||
ReadDirectives();
|
ReadDirectives();
|
||||||
|
|
||||||
|
@ -126,7 +127,8 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||||
if( !readModel( *symbol, spiceItem ) )
|
if( !readModel( *symbol, spiceItem ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
readPins( *symbol, spiceItem, notConnectedCounter );
|
readPinNumbers( *symbol, spiceItem );
|
||||||
|
readPinNetNames( *symbol, spiceItem, NCCounter );
|
||||||
|
|
||||||
// TODO: transmission line handling?
|
// TODO: transmission line handling?
|
||||||
|
|
||||||
|
@ -211,8 +213,8 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives()
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
DisplayErrorMessage( nullptr,
|
DisplayErrorMessage( nullptr,
|
||||||
wxString::Format( "Failed reading model library '%s'.", path ),
|
wxString::Format( "Failed reading model library '%s'.", path ),
|
||||||
e.What() );
|
e.What() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -326,9 +328,9 @@ bool NETLIST_EXPORTER_SPICE::readModel( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special case for legacy models.
|
||||||
if( auto model = dynamic_cast<const SIM_MODEL_SPICE*>( aItem.model.get() ) )
|
if( auto model = dynamic_cast<const SIM_MODEL_SPICE*>( aItem.model.get() ) )
|
||||||
{
|
{
|
||||||
// Special case for legacy models.
|
|
||||||
unsigned libParamIndex = static_cast<unsigned>( SIM_MODEL_SPICE::SPICE_PARAM::LIB );
|
unsigned libParamIndex = static_cast<unsigned>( SIM_MODEL_SPICE::SPICE_PARAM::LIB );
|
||||||
wxString path = model->GetParam( libParamIndex ).value->ToString();
|
wxString path = model->GetParam( libParamIndex ).value->ToString();
|
||||||
|
|
||||||
|
@ -340,19 +342,28 @@ bool NETLIST_EXPORTER_SPICE::readModel( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NETLIST_EXPORTER_SPICE::readPins( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
|
void NETLIST_EXPORTER_SPICE::readPinNumbers( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
||||||
int& notConnectedCounter )
|
|
||||||
{
|
{
|
||||||
for( const PIN_INFO& pin : m_sortedSymbolPinList )
|
for( const LIB_PIN* pin : aSymbol.GetLibPins() )
|
||||||
|
aItem.pinNumbers.push_back( pin->GetShownNumber() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NETLIST_EXPORTER_SPICE::readPinNetNames( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
|
||||||
|
int& aNCCounter )
|
||||||
|
{
|
||||||
|
for( const PIN_INFO& pinInfo : m_sortedSymbolPinList )
|
||||||
{
|
{
|
||||||
wxString netName = pin.netName;
|
wxString netName = pinInfo.netName;
|
||||||
ReplaceForbiddenChars( netName );
|
ReplaceForbiddenChars( netName );
|
||||||
netName = UnescapeString( netName );
|
netName = UnescapeString( netName );
|
||||||
|
|
||||||
if( netName.IsEmpty() )
|
LOCALE_IO toggle;
|
||||||
netName = wxString::Format( wxT( "NC_%.2u" ), notConnectedCounter++ );
|
|
||||||
|
|
||||||
aItem.pins.push_back( netName );
|
if( netName == "" )
|
||||||
|
netName = wxString::Format( wxT( "__NC_%.2u" ), aNCCounter++ );
|
||||||
|
|
||||||
|
aItem.pinNetNames.push_back( netName );
|
||||||
m_nets.insert( netName );
|
m_nets.insert( netName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,9 +426,11 @@ void NETLIST_EXPORTER_SPICE::writeItems( OUTPUTFORMATTER& aFormatter )
|
||||||
if( !item.model->IsEnabled() )
|
if( !item.model->IsEnabled() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
aFormatter.Print( 0, "%s", TO_UTF8( item.model->GenerateSpiceItemLine( item.refName,
|
aFormatter.Print( 0, "%s",
|
||||||
item.modelName,
|
TO_UTF8( item.model->GenerateSpiceItemLine( item.refName,
|
||||||
item.pins ) ) );
|
item.modelName,
|
||||||
|
item.pinNumbers,
|
||||||
|
item.pinNetNames ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ struct SPICE_ITEM
|
||||||
{
|
{
|
||||||
wxString refName;
|
wxString refName;
|
||||||
wxString libraryPath;
|
wxString libraryPath;
|
||||||
std::vector<wxString> pins;
|
std::vector<wxString> pinNumbers;
|
||||||
|
std::vector<wxString> pinNetNames;
|
||||||
std::unique_ptr<const SIM_MODEL> model;
|
std::unique_ptr<const SIM_MODEL> model;
|
||||||
wxString modelName;
|
wxString modelName;
|
||||||
};
|
};
|
||||||
|
@ -112,7 +113,8 @@ private:
|
||||||
bool readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
|
bool readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
|
||||||
std::set<wxString>& aRefNames );
|
std::set<wxString>& aRefNames );
|
||||||
bool readModel( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
|
bool readModel( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
|
||||||
void readPins( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem, int& notConnectedCounter );
|
void readPinNumbers( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
|
||||||
|
void readPinNetNames( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem, int& aNCCounter );
|
||||||
|
|
||||||
void writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
|
void writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
|
||||||
const wxString& aPath );
|
const wxString& aPath );
|
||||||
|
|
|
@ -920,6 +920,15 @@ void SCH_SYMBOL::GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<LIB_PIN*> SCH_SYMBOL::GetLibPins() const
|
||||||
|
{
|
||||||
|
std::vector<LIB_PIN*> pinList;
|
||||||
|
|
||||||
|
GetLibPins( pinList );
|
||||||
|
return pinList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SCH_PIN* SCH_SYMBOL::GetPin( LIB_PIN* aLibPin ) const
|
SCH_PIN* SCH_SYMBOL::GetPin( LIB_PIN* aLibPin ) const
|
||||||
{
|
{
|
||||||
wxASSERT( m_pinMap.count( aLibPin ) );
|
wxASSERT( m_pinMap.count( aLibPin ) );
|
||||||
|
@ -952,17 +961,6 @@ std::vector<SCH_PIN*> SCH_SYMBOL::GetPins( const SCH_SHEET_PATH* aSheet ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<SCH_PIN*> SCH_SYMBOL::GetAllPins() const
|
|
||||||
{
|
|
||||||
std::vector<SCH_PIN*> pins;
|
|
||||||
|
|
||||||
for( const auto& p : m_pins )
|
|
||||||
pins.push_back( p.get() );
|
|
||||||
|
|
||||||
return pins;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SCH_SYMBOL::SwapData( SCH_ITEM* aItem )
|
void SCH_SYMBOL::SwapData( SCH_ITEM* aItem )
|
||||||
{
|
{
|
||||||
wxCHECK_RET( (aItem != nullptr) && (aItem->Type() == SCH_SYMBOL_T),
|
wxCHECK_RET( (aItem != nullptr) && (aItem->Type() == SCH_SYMBOL_T),
|
||||||
|
|
|
@ -467,6 +467,13 @@ public:
|
||||||
*/
|
*/
|
||||||
void GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const;
|
void GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a vector with all the pins from the library object.
|
||||||
|
*
|
||||||
|
* @return List of the pins
|
||||||
|
*/
|
||||||
|
std::vector<LIB_PIN*> GetLibPins() const;
|
||||||
|
|
||||||
SCH_PIN* GetPin( LIB_PIN* aLibPin ) const;
|
SCH_PIN* GetPin( LIB_PIN* aLibPin ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -117,7 +117,7 @@ SIM_MODEL::DEVICE_INFO SIM_MODEL::DeviceTypeInfo( DEVICE_TYPE_ aDeviceType )
|
||||||
SIM_MODEL::INFO SIM_MODEL::TypeInfo( TYPE aType )
|
SIM_MODEL::INFO SIM_MODEL::TypeInfo( TYPE aType )
|
||||||
{
|
{
|
||||||
switch( aType )
|
switch( aType )
|
||||||
{
|
{
|
||||||
case TYPE::NONE: return { DEVICE_TYPE_::NONE, "", "" };
|
case TYPE::NONE: return { DEVICE_TYPE_::NONE, "", "" };
|
||||||
|
|
||||||
case TYPE::R: return { DEVICE_TYPE_::R, "", "Ideal" };
|
case TYPE::R: return { DEVICE_TYPE_::R, "", "Ideal" };
|
||||||
|
@ -139,7 +139,7 @@ SIM_MODEL::INFO SIM_MODEL::TypeInfo( TYPE aType )
|
||||||
case TYPE::SW_I: return { DEVICE_TYPE_::SW, "I", "Current-controlled" };
|
case TYPE::SW_I: return { DEVICE_TYPE_::SW, "I", "Current-controlled" };
|
||||||
|
|
||||||
case TYPE::D: return { DEVICE_TYPE_::D, "", "" };
|
case TYPE::D: return { DEVICE_TYPE_::D, "", "" };
|
||||||
|
|
||||||
case TYPE::NPN_GUMMELPOON: return { DEVICE_TYPE_::NPN, "GUMMELPOON", "Gummel-Poon" };
|
case TYPE::NPN_GUMMELPOON: return { DEVICE_TYPE_::NPN, "GUMMELPOON", "Gummel-Poon" };
|
||||||
case TYPE::PNP_GUMMELPOON: return { DEVICE_TYPE_::PNP, "GUMMELPOON", "Gummel-Poon" };
|
case TYPE::PNP_GUMMELPOON: return { DEVICE_TYPE_::PNP, "GUMMELPOON", "Gummel-Poon" };
|
||||||
case TYPE::NPN_VBIC: return { DEVICE_TYPE_::NPN, "VBIC", "VBIC" };
|
case TYPE::NPN_VBIC: return { DEVICE_TYPE_::NPN, "VBIC", "VBIC" };
|
||||||
|
@ -261,7 +261,7 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType )
|
||||||
case TYPE::L: return { "L", "" };
|
case TYPE::L: return { "L", "" };
|
||||||
//case TYPE::L_ADV: return { "L", "l" };
|
//case TYPE::L_ADV: return { "L", "l" };
|
||||||
case TYPE::L_BEHAVIORAL: return { "L", "", "", "0", false, true };
|
case TYPE::L_BEHAVIORAL: return { "L", "", "", "0", false, true };
|
||||||
|
|
||||||
case TYPE::TLINE_Z0: return { "T" };
|
case TYPE::TLINE_Z0: return { "T" };
|
||||||
case TYPE::TLINE_RLGC: return { "O", "ltra" };
|
case TYPE::TLINE_RLGC: return { "O", "ltra" };
|
||||||
|
|
||||||
|
@ -602,7 +602,7 @@ TYPE SIM_MODEL::InferTypeFromRefAndValue( const wxString& aRef, const wxString&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( const tao::pegtl::parse_error& )
|
catch( const tao::pegtl::parse_error& e )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,8 +853,6 @@ void SIM_MODEL::ReadSpiceCode( const wxString& aSpiceCode )
|
||||||
}
|
}
|
||||||
catch( tao::pegtl::parse_error& e )
|
catch( tao::pegtl::parse_error& e )
|
||||||
{
|
{
|
||||||
wxString msg;
|
|
||||||
msg.Printf( _( "Error parsing spice code <%s>\n%s" ), aSpiceCode, e.what() );
|
|
||||||
THROW_IO_ERROR( e.what() );
|
THROW_IO_ERROR( e.what() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,18 +923,18 @@ wxString SIM_MODEL::GenerateSpiceModelLine( const wxString& aModelName ) const
|
||||||
|
|
||||||
wxString valueStr = param.value->ToSpiceString();
|
wxString valueStr = param.value->ToSpiceString();
|
||||||
|
|
||||||
if( valueStr.IsEmpty() )
|
if( valueStr == "" )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
wxString appendix = " " + param.info.name + "=" + valueStr;
|
||||||
|
|
||||||
wxString append = " " + param.info.name + "=" + valueStr;
|
if( line.Length() + appendix.Length() > 60 )
|
||||||
|
|
||||||
if( line.Length() + append.Length() > 60 )
|
|
||||||
{
|
{
|
||||||
result << line + "\n";
|
result << line << "\n";
|
||||||
line = "+" + append;
|
line = "+" + appendix;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
line << append;
|
line << appendix;
|
||||||
}
|
}
|
||||||
|
|
||||||
result << line + " )\n";
|
result << line + " )\n";
|
||||||
|
@ -956,16 +954,33 @@ wxString SIM_MODEL::GenerateSpiceItemName( const wxString& aRefName ) const
|
||||||
wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName,
|
wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName ) const
|
const wxString& aModelName ) const
|
||||||
{
|
{
|
||||||
std::vector<wxString> pinNames;
|
// Use linear symbol pin numbers enumeration. Used in model preview.
|
||||||
for( const PIN& pin : GetPins() )
|
|
||||||
pinNames.push_back( pin.name );
|
|
||||||
|
|
||||||
return GenerateSpiceItemLine( aRefName, aModelName, pinNames );
|
std::vector<wxString> pinNumbers;
|
||||||
|
|
||||||
|
for( int i = 0; i < GetPinCount(); ++i )
|
||||||
|
pinNumbers.push_back( wxString::FromCDouble( i + 1 ) );
|
||||||
|
|
||||||
|
return GenerateSpiceItemLine( aRefName, aModelName, pinNumbers );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName,
|
wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers ) const
|
||||||
|
{
|
||||||
|
std::vector<wxString> pinNames;
|
||||||
|
|
||||||
|
for( const PIN& pin : GetPins() )
|
||||||
|
pinNames.push_back( pin.name );
|
||||||
|
|
||||||
|
return GenerateSpiceItemLine( aRefName, aModelName, aSymbolPinNumbers, pinNames );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const
|
const std::vector<wxString>& aPinNetNames ) const
|
||||||
{
|
{
|
||||||
wxString result = "";
|
wxString result = "";
|
||||||
|
@ -973,12 +988,20 @@ wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
|
|
||||||
for( const PIN& pin : GetPins() )
|
for( const PIN& pin : GetPins() )
|
||||||
{
|
{
|
||||||
for( unsigned i = 0; i < aPinNetNames.size(); ++i )
|
int ncCounter = 0;
|
||||||
{
|
auto it = std::find( aSymbolPinNumbers.begin(),
|
||||||
unsigned symbolPinNumber = i + 1;
|
aSymbolPinNumbers.end(),
|
||||||
|
pin.symbolPinNumber );
|
||||||
|
|
||||||
if( symbolPinNumber == pin.symbolPinNumber )
|
if( it == aSymbolPinNumbers.end() )
|
||||||
result << aPinNetNames[i] << " ";
|
{
|
||||||
|
LOCALE_IO toggle;
|
||||||
|
result << wxString::Format( "__NC_%s_%s_%.2u", aRefName, aModelName, ncCounter++ );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
long symbolPinIndex = std::distance( aSymbolPinNumbers.begin(), it );
|
||||||
|
result << aPinNetNames.at( symbolPinIndex ) << " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -992,7 +1015,7 @@ wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
|
|
||||||
wxString name = ( param.info.spiceInstanceName == "" ) ?
|
wxString name = ( param.info.spiceInstanceName == "" ) ?
|
||||||
param.info.name : param.info.spiceInstanceName;
|
param.info.name : param.info.spiceInstanceName;
|
||||||
wxString value = param.value->ToString( SIM_VALUE_GRAMMAR::NOTATION::SPICE );
|
wxString value = param.value->ToSpiceString();
|
||||||
|
|
||||||
if( value != "" )
|
if( value != "" )
|
||||||
result << name << "=" << value << " ";
|
result << name << "=" << value << " ";
|
||||||
|
@ -1042,15 +1065,15 @@ void SIM_MODEL::AddPin( const PIN& aPin )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned SIM_MODEL::FindModelPinNumber( unsigned aSymbolPinNumber )
|
int SIM_MODEL::FindModelPinIndex( const wxString& aSymbolPinNumber )
|
||||||
{
|
{
|
||||||
for( unsigned i = 0; i < GetPinCount(); ++i )
|
for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex )
|
||||||
{
|
{
|
||||||
if( GetPin( i ).symbolPinNumber == aSymbolPinNumber )
|
if( GetPin( modelPinIndex ).symbolPinNumber == aSymbolPinNumber )
|
||||||
return i + 1;
|
return modelPinIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return PIN::NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1064,8 +1087,8 @@ std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> SIM_MODEL::GetPins() c
|
||||||
{
|
{
|
||||||
std::vector<std::reference_wrapper<const PIN>> pins;
|
std::vector<std::reference_wrapper<const PIN>> pins;
|
||||||
|
|
||||||
for( unsigned i = 0; i < GetPinCount(); ++i )
|
for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex )
|
||||||
pins.emplace_back( GetPin( i ) );
|
pins.emplace_back( GetPin( modelPinIndex ) );
|
||||||
|
|
||||||
return pins;
|
return pins;
|
||||||
}
|
}
|
||||||
|
@ -1101,8 +1124,8 @@ std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> SIM_MODEL::GetParams
|
||||||
{
|
{
|
||||||
std::vector<std::reference_wrapper<const PARAM>> params;
|
std::vector<std::reference_wrapper<const PARAM>> params;
|
||||||
|
|
||||||
for( unsigned i = 0; i < GetParamCount(); ++i )
|
for( int i = 0; i < GetParamCount(); ++i )
|
||||||
params.emplace_back( GetParam( i ) );
|
params.push_back( GetParam( i ) );
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1167,7 @@ bool SIM_MODEL::SetParamValue( const wxString& aParamName, const wxString& aValu
|
||||||
{
|
{
|
||||||
return param.info.name == aParamName.Lower();
|
return param.info.name == aParamName.Lower();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if( it == params.end() )
|
if( it == params.end() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1199,12 +1222,12 @@ void SIM_MODEL::CreatePins( unsigned aSymbolPinCount )
|
||||||
// Default pin sequence: model pins are the same as symbol pins.
|
// Default pin sequence: model pins are the same as symbol pins.
|
||||||
// Excess model pins are set as Not Connected.
|
// Excess model pins are set as Not Connected.
|
||||||
// Note that intentionally nothing is added if `getPinNames()` returns an empty vector.
|
// Note that intentionally nothing is added if `getPinNames()` returns an empty vector.
|
||||||
for( unsigned i = 0; i < getPinNames().size(); ++i )
|
for( unsigned modelPinIndex = 0; modelPinIndex < getPinNames().size(); ++modelPinIndex )
|
||||||
{
|
{
|
||||||
if( i < aSymbolPinCount )
|
if( modelPinIndex < aSymbolPinCount )
|
||||||
AddPin( { getPinNames().at( i ), i + 1 } );
|
AddPin( { getPinNames().at( modelPinIndex ), wxString::FromCDouble( modelPinIndex + 1 ) } );
|
||||||
else
|
else
|
||||||
AddPin( { getPinNames().at( i ), PIN::NOT_CONNECTED } );
|
AddPin( { getPinNames().at( modelPinIndex ), "" } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1218,8 +1241,8 @@ template <typename T>
|
||||||
void SIM_MODEL::WriteInferredDataFields( std::vector<T>& aFields, const wxString& aValue ) const
|
void SIM_MODEL::WriteInferredDataFields( std::vector<T>& aFields, const wxString& aValue ) const
|
||||||
{
|
{
|
||||||
if( GetPinCount() == 2
|
if( GetPinCount() == 2
|
||||||
&& GetPin( 0 ).symbolPinNumber == 1
|
&& GetPin( 0 ).symbolPinNumber == "1"
|
||||||
&& GetPin( 1 ).symbolPinNumber == 2 )
|
&& GetPin( 1 ).symbolPinNumber == "2" )
|
||||||
{
|
{
|
||||||
SetFieldValue( aFields, PINS_FIELD, "" );
|
SetFieldValue( aFields, PINS_FIELD, "" );
|
||||||
}
|
}
|
||||||
|
@ -1276,13 +1299,14 @@ wxString SIM_MODEL::GenerateParamsField( const wxString& aPairSeparator ) const
|
||||||
void SIM_MODEL::ParseParamsField( const wxString& aParamsField )
|
void SIM_MODEL::ParseParamsField( const wxString& aParamsField )
|
||||||
{
|
{
|
||||||
LOCALE_IO toggle;
|
LOCALE_IO toggle;
|
||||||
|
|
||||||
tao::pegtl::string_input<> in( aParamsField.ToUTF8(), "Sim_Params" );
|
tao::pegtl::string_input<> in( aParamsField.ToUTF8(), "Sim_Params" );
|
||||||
std::unique_ptr<tao::pegtl::parse_tree::node> root;
|
std::unique_ptr<tao::pegtl::parse_tree::node> root;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Using parse tree instead of actions because we don't care about performance that much,
|
// Using parse tree instead of actions because we don't care about performance that much,
|
||||||
// and having a tree greatly simplifies some things.
|
// and having a tree greatly simplifies some things.
|
||||||
root = tao::pegtl::parse_tree::parse<
|
root = tao::pegtl::parse_tree::parse<
|
||||||
SIM_MODEL_PARSER::fieldParamValuePairsGrammar,
|
SIM_MODEL_PARSER::fieldParamValuePairsGrammar,
|
||||||
SIM_MODEL_PARSER::fieldParamValuePairsSelector>
|
SIM_MODEL_PARSER::fieldParamValuePairsSelector>
|
||||||
|
@ -1290,9 +1314,7 @@ void SIM_MODEL::ParseParamsField( const wxString& aParamsField )
|
||||||
}
|
}
|
||||||
catch( const tao::pegtl::parse_error& e )
|
catch( const tao::pegtl::parse_error& e )
|
||||||
{
|
{
|
||||||
wxString msg;
|
THROW_IO_ERROR( e.what() );
|
||||||
msg.Printf( _( "Error parsing param <%s>\n%s" ), aParamsField, e.what() );
|
|
||||||
THROW_IO_ERROR( msg );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString paramName = "";
|
wxString paramName = "";
|
||||||
|
@ -1303,7 +1325,7 @@ void SIM_MODEL::ParseParamsField( const wxString& aParamsField )
|
||||||
paramName = node->string();
|
paramName = node->string();
|
||||||
// TODO: Do something with number<SIM_VALUE::TYPE_INT, ...>.
|
// TODO: Do something with number<SIM_VALUE::TYPE_INT, ...>.
|
||||||
// It doesn't seem too useful?
|
// It doesn't seem too useful?
|
||||||
else if( node->is_type<SIM_MODEL_PARSER::quotedStringContent>()
|
else if( node->is_type<SIM_MODEL_PARSER::quotedStringContent>()
|
||||||
|| node->is_type<SIM_MODEL_PARSER::unquotedString>() )
|
|| node->is_type<SIM_MODEL_PARSER::unquotedString>() )
|
||||||
{
|
{
|
||||||
wxASSERT( paramName != "" );
|
wxASSERT( paramName != "" );
|
||||||
|
@ -1347,12 +1369,10 @@ void SIM_MODEL::ParsePinsField( unsigned aSymbolPinCount, const wxString& aPinsF
|
||||||
}
|
}
|
||||||
catch( const tao::pegtl::parse_error& e )
|
catch( const tao::pegtl::parse_error& e )
|
||||||
{
|
{
|
||||||
wxString msg;
|
|
||||||
msg.Printf( _( "Error parsing pin field <%s>\n%s" ), aPinsField, e.what() );
|
|
||||||
THROW_IO_ERROR( e.what() );
|
THROW_IO_ERROR( e.what() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( root->children.size() != GetPinCount() )
|
if( static_cast<int>( root->children.size() ) != GetPinCount() )
|
||||||
{
|
{
|
||||||
THROW_IO_ERROR( wxString::Format( _( "%s describes %lu pins, expected %u" ),
|
THROW_IO_ERROR( wxString::Format( _( "%s describes %lu pins, expected %u" ),
|
||||||
PINS_FIELD,
|
PINS_FIELD,
|
||||||
|
@ -1360,13 +1380,12 @@ void SIM_MODEL::ParsePinsField( unsigned aSymbolPinCount, const wxString& aPinsF
|
||||||
GetPinCount() ) );
|
GetPinCount() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned i = 0; i < root->children.size(); ++i )
|
for( int pinIndex = 0; pinIndex < static_cast<int>( root->children.size() ); ++pinIndex )
|
||||||
{
|
{
|
||||||
if( root->children.at( i )->string() == "X" )
|
if( root->children.at( pinIndex )->string() == "~" )
|
||||||
SetPinSymbolPinNumber( static_cast<int>( i ), PIN::NOT_CONNECTED );
|
SetPinSymbolPinNumber( pinIndex, "" );
|
||||||
else
|
else
|
||||||
SetPinSymbolPinNumber( static_cast<int>( i ),
|
SetPinSymbolPinNumber( pinIndex, root->children.at( pinIndex )->string() );
|
||||||
std::stoi( root->children.at( i )->string() ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1405,7 +1424,7 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::create( TYPE aType )
|
||||||
case TYPE::V_BEHAVIORAL:
|
case TYPE::V_BEHAVIORAL:
|
||||||
case TYPE::I_BEHAVIORAL:
|
case TYPE::I_BEHAVIORAL:
|
||||||
return std::make_unique<SIM_MODEL_BEHAVIORAL>( aType );
|
return std::make_unique<SIM_MODEL_BEHAVIORAL>( aType );
|
||||||
|
|
||||||
case TYPE::TLINE_Z0:
|
case TYPE::TLINE_Z0:
|
||||||
case TYPE::TLINE_RLGC:
|
case TYPE::TLINE_RLGC:
|
||||||
return std::make_unique<SIM_MODEL_TLINE>( aType );
|
return std::make_unique<SIM_MODEL_TLINE>( aType );
|
||||||
|
@ -1548,17 +1567,17 @@ wxString SIM_MODEL::generatePinsField() const
|
||||||
wxString result = "";
|
wxString result = "";
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
|
|
||||||
for( unsigned i = 0; i < GetPinCount(); ++i )
|
for( int pinIndex = 0; pinIndex < GetPinCount(); ++pinIndex )
|
||||||
{
|
{
|
||||||
if( isFirst )
|
if( isFirst )
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
else
|
else
|
||||||
result << " ";
|
result << " ";
|
||||||
|
|
||||||
if( GetPin( i ).symbolPinNumber == PIN::NOT_CONNECTED )
|
if( GetPin( pinIndex ).symbolPinNumber == "" )
|
||||||
result << "X";
|
result << "~";
|
||||||
else
|
else
|
||||||
result << GetPin( i ).symbolPinNumber;
|
result << GetPin( pinIndex ).symbolPinNumber; // Note that it's numbered from 1.
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -51,10 +51,12 @@ namespace SIM_MODEL_GRAMMAR
|
||||||
star<sep,
|
star<sep,
|
||||||
legacyPinNumber>> {};
|
legacyPinNumber>> {};
|
||||||
|
|
||||||
struct legacyPinSequenceGrammar : must<legacyPinSequence, tao::pegtl::eof> {};
|
struct legacyPinSequenceGrammar : must<legacyPinSequence,
|
||||||
|
tao::pegtl::eof> {};
|
||||||
|
|
||||||
|
|
||||||
struct pinNumber : sor<digits, one<'X'>> {};
|
struct pinNumber : plus<not_at<sep>,
|
||||||
|
any> {};
|
||||||
struct pinSequence : seq<opt<pinNumber>,
|
struct pinSequence : seq<opt<pinNumber>,
|
||||||
star<sep,
|
star<sep,
|
||||||
pinNumber>> {};
|
pinNumber>> {};
|
||||||
|
@ -64,16 +66,17 @@ namespace SIM_MODEL_GRAMMAR
|
||||||
opt<sep>,
|
opt<sep>,
|
||||||
tao::pegtl::eof> {};
|
tao::pegtl::eof> {};
|
||||||
|
|
||||||
struct unquotedString : plus<not_at<space>, any> {};
|
|
||||||
|
struct unquotedString : plus<not_at<sep>, any> {};
|
||||||
struct quotedStringContent : star<not_at<one<'"'>>, any> {}; // TODO: Allow escaping '"'.
|
struct quotedStringContent : star<not_at<one<'"'>>, any> {}; // TODO: Allow escaping '"'.
|
||||||
struct quotedString : seq<one<'"'>,
|
struct quotedString : seq<one<'"'>,
|
||||||
quotedStringContent,
|
quotedStringContent,
|
||||||
one<'"'>> {};
|
one<'"'>> {};
|
||||||
|
|
||||||
struct fieldFloatValue : seq<star<space>,
|
struct fieldFloatValue : seq<opt<sep>,
|
||||||
number<SIM_VALUE::TYPE_FLOAT, NOTATION::SI>,
|
number<SIM_VALUE::TYPE_FLOAT, NOTATION::SI>,
|
||||||
star<not_at<space>, any>, // Garbage suffix.
|
star<not_at<sep>, any>, // Garbage suffix.
|
||||||
star<space>> {};
|
opt<sep>> {};
|
||||||
|
|
||||||
struct fieldFloatValueGrammar : must<fieldFloatValue,
|
struct fieldFloatValueGrammar : must<fieldFloatValue,
|
||||||
tao::pegtl::eof> {};
|
tao::pegtl::eof> {};
|
||||||
|
@ -324,10 +327,10 @@ public:
|
||||||
|
|
||||||
struct PIN
|
struct PIN
|
||||||
{
|
{
|
||||||
static constexpr unsigned NOT_CONNECTED = 0;
|
|
||||||
|
|
||||||
const wxString name;
|
const wxString name;
|
||||||
unsigned symbolPinNumber;
|
wxString symbolPinNumber;
|
||||||
|
|
||||||
|
static constexpr auto NOT_CONNECTED = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -489,8 +492,12 @@ public:
|
||||||
|
|
||||||
virtual wxString GenerateSpiceItemName( const wxString& aRefName ) const;
|
virtual wxString GenerateSpiceItemName( const wxString& aRefName ) const;
|
||||||
wxString GenerateSpiceItemLine( const wxString& aRefName, const wxString& aModelName ) const;
|
wxString GenerateSpiceItemLine( const wxString& aRefName, const wxString& aModelName ) const;
|
||||||
|
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers ) const;
|
||||||
virtual wxString GenerateSpiceItemLine( const wxString& aRefName,
|
virtual wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const;
|
const std::vector<wxString>& aPinNetNames ) const;
|
||||||
|
|
||||||
virtual wxString GenerateSpiceTuningLine( const wxString& aSymbol ) const;
|
virtual wxString GenerateSpiceTuningLine( const wxString& aSymbol ) const;
|
||||||
|
@ -501,7 +508,7 @@ public:
|
||||||
virtual std::vector<wxString> GenerateSpiceCurrentNames( const wxString& aRefName ) const;
|
virtual std::vector<wxString> GenerateSpiceCurrentNames( const wxString& aRefName ) const;
|
||||||
|
|
||||||
void AddPin( const PIN& aPin );
|
void AddPin( const PIN& aPin );
|
||||||
unsigned FindModelPinNumber( unsigned aSymbolPinNumber );
|
int FindModelPinIndex( const wxString& aSymbolPinNumber );
|
||||||
void AddParam( const PARAM::INFO& aInfo, bool aIsOtherVariant = false );
|
void AddParam( const PARAM::INFO& aInfo, bool aIsOtherVariant = false );
|
||||||
|
|
||||||
DEVICE_INFO GetDeviceTypeInfo() const { return DeviceTypeInfo( GetDeviceType() ); }
|
DEVICE_INFO GetDeviceTypeInfo() const { return DeviceTypeInfo( GetDeviceType() ); }
|
||||||
|
@ -513,18 +520,18 @@ public:
|
||||||
const SIM_MODEL* GetBaseModel() const { return m_baseModel; }
|
const SIM_MODEL* GetBaseModel() const { return m_baseModel; }
|
||||||
virtual void SetBaseModel( const SIM_MODEL& aBaseModel ) { m_baseModel = &aBaseModel; }
|
virtual void SetBaseModel( const SIM_MODEL& aBaseModel ) { m_baseModel = &aBaseModel; }
|
||||||
|
|
||||||
unsigned GetPinCount() const { return m_pins.size(); }
|
int GetPinCount() const { return static_cast<int>( m_pins.size() ); }
|
||||||
const PIN& GetPin( unsigned aIndex ) const { return m_pins.at( aIndex ); }
|
const PIN& GetPin( unsigned aIndex ) const { return m_pins.at( aIndex ); }
|
||||||
|
|
||||||
std::vector<std::reference_wrapper<const PIN>> GetPins() const;
|
std::vector<std::reference_wrapper<const PIN>> GetPins() const;
|
||||||
|
|
||||||
void SetPinSymbolPinNumber( int aIndex, int aSymbolPinNumber )
|
void SetPinSymbolPinNumber( int aPinIndex, const wxString& aSymbolPinNumber )
|
||||||
{
|
{
|
||||||
m_pins.at( aIndex ).symbolPinNumber = aSymbolPinNumber;
|
m_pins.at( aPinIndex ).symbolPinNumber = aSymbolPinNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned GetParamCount() const { return m_params.size(); }
|
int GetParamCount() const { return static_cast<int>( m_params.size() ); }
|
||||||
const PARAM& GetParam( unsigned aParamIndex ) const; // Return base parameter unless it's overridden.
|
const PARAM& GetParam( unsigned aParamIndex ) const; // Return base parameter unless it's overridden.
|
||||||
|
|
||||||
const PARAM* FindParam( const wxString& aParamName ) const;
|
const PARAM* FindParam( const wxString& aParamName ) const;
|
||||||
|
|
|
@ -95,6 +95,7 @@ wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceModelLine( const wxString& aModelNam
|
||||||
|
|
||||||
wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceItemLine( const wxString& aRefName,
|
wxString SIM_MODEL_BEHAVIORAL::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const
|
const std::vector<wxString>& aPinNetNames ) const
|
||||||
{
|
{
|
||||||
LOCALE_IO toggle;
|
LOCALE_IO toggle;
|
||||||
|
|
|
@ -45,6 +45,7 @@ public:
|
||||||
|
|
||||||
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const override;
|
const std::vector<wxString>& aPinNetNames ) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -104,12 +104,13 @@ wxString SIM_MODEL_IDEAL::GenerateSpiceModelLine( const wxString& aModelName ) c
|
||||||
|
|
||||||
wxString SIM_MODEL_IDEAL::GenerateSpiceItemLine( const wxString& aRefName,
|
wxString SIM_MODEL_IDEAL::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const
|
const std::vector<wxString>& aPinNetNames ) const
|
||||||
{
|
{
|
||||||
wxString valueStr = GetParam( 0 ).value->ToString( SIM_VALUE::NOTATION::SPICE );
|
wxString valueStr = GetParam( 0 ).value->ToString( SIM_VALUE::NOTATION::SPICE );
|
||||||
|
|
||||||
if( valueStr != "" )
|
if( valueStr != "" )
|
||||||
return SIM_MODEL::GenerateSpiceItemLine( aRefName, valueStr, aPinNetNames );
|
return SIM_MODEL::GenerateSpiceItemLine( aRefName, valueStr, aSymbolPinNumbers, aPinNetNames );
|
||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
|
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
|
||||||
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const override;
|
const std::vector<wxString>& aPinNetNames ) const override;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ wxString SIM_MODEL_SOURCE::GenerateSpiceModelLine( const wxString& aModelName )
|
||||||
|
|
||||||
wxString SIM_MODEL_SOURCE::GenerateSpiceItemLine( const wxString& aRefName,
|
wxString SIM_MODEL_SOURCE::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const
|
const std::vector<wxString>& aPinNetNames ) const
|
||||||
{
|
{
|
||||||
wxString model;
|
wxString model;
|
||||||
|
@ -230,7 +231,7 @@ wxString SIM_MODEL_SOURCE::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
else
|
else
|
||||||
model << GetParam( 0 ).value->ToString( SIM_VALUE_GRAMMAR::NOTATION::SPICE );
|
model << GetParam( 0 ).value->ToString( SIM_VALUE_GRAMMAR::NOTATION::SPICE );
|
||||||
|
|
||||||
return SIM_MODEL::GenerateSpiceItemLine( aRefName, model, aPinNetNames );
|
return SIM_MODEL::GenerateSpiceItemLine( aRefName, model, aSymbolPinNumbers, aPinNetNames );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -241,15 +242,15 @@ bool SIM_MODEL_SOURCE::SetParamValue( unsigned aParamIndex, const wxString& aVal
|
||||||
// them out automatically. If a value is nulled, delete everything after it.
|
// them out automatically. If a value is nulled, delete everything after it.
|
||||||
if( aValue == "" )
|
if( aValue == "" )
|
||||||
{
|
{
|
||||||
for( unsigned i = aParamIndex; i < GetParamCount(); ++i )
|
for( int paramIndex = aParamIndex; paramIndex < GetParamCount(); ++paramIndex )
|
||||||
SIM_MODEL::SetParamValue( i, "", aNotation );
|
SIM_MODEL::SetParamValue( paramIndex, "", aNotation );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for( unsigned i = 0; i < aParamIndex; ++i )
|
for( unsigned paramIndex = 0; paramIndex < aParamIndex; ++paramIndex )
|
||||||
{
|
{
|
||||||
if( GetParam( i ).value->ToString() == "" )
|
if( GetParam( paramIndex ).value->ToString() == "" )
|
||||||
SIM_MODEL::SetParamValue( i, "0", aNotation );
|
SIM_MODEL::SetParamValue( paramIndex, "0", aNotation );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
|
wxString GenerateSpiceModelLine( const wxString& aModelName ) const override;
|
||||||
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const override;
|
const std::vector<wxString>& aPinNetNames ) const override;
|
||||||
|
|
||||||
bool SetParamValue( unsigned aParamIndex, const wxString& aValue,
|
bool SetParamValue( unsigned aParamIndex, const wxString& aValue,
|
||||||
|
|
|
@ -100,20 +100,20 @@ wxString SIM_MODEL_SPICE::GenerateSpiceItemName( const wxString& aRefName ) cons
|
||||||
|
|
||||||
wxString SIM_MODEL_SPICE::GenerateSpiceItemLine( const wxString& aRefName,
|
wxString SIM_MODEL_SPICE::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const
|
const std::vector<wxString>& aPinNetNames ) const
|
||||||
{
|
{
|
||||||
wxString result = "";
|
wxString result;
|
||||||
result << GenerateSpiceItemName( aRefName ) << " ";
|
result << GenerateSpiceItemName( aRefName ) << " ";
|
||||||
|
|
||||||
for( unsigned i = 0; i < GetPinCount(); ++i )
|
for( const PIN& pin : GetPins() )
|
||||||
{
|
{
|
||||||
for( unsigned j = 0; j < aPinNetNames.size(); ++j )
|
auto it = std::find( aSymbolPinNumbers.begin(),
|
||||||
{
|
aSymbolPinNumbers.end(),
|
||||||
unsigned symbolPinNumber = j + 1;
|
pin.symbolPinNumber );
|
||||||
|
long symbolPinIndex = std::distance( aSymbolPinNumbers.begin(), it );
|
||||||
|
|
||||||
if( symbolPinNumber == GetPin( i ).symbolPinNumber )
|
result << aPinNetNames.at( symbolPinIndex ) << " ";
|
||||||
result << aPinNetNames[j] << " ";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result << GetParam( static_cast<unsigned>( SPICE_PARAM::MODEL ) ).value->ToString() << "\n";
|
result << GetParam( static_cast<unsigned>( SPICE_PARAM::MODEL ) ).value->ToString() << "\n";
|
||||||
|
@ -123,8 +123,8 @@ wxString SIM_MODEL_SPICE::GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
|
|
||||||
void SIM_MODEL_SPICE::CreatePins( unsigned aSymbolPinCount )
|
void SIM_MODEL_SPICE::CreatePins( unsigned aSymbolPinCount )
|
||||||
{
|
{
|
||||||
for( unsigned i = 0; i < aSymbolPinCount; ++i )
|
for( unsigned symbolPinIndex = 0; symbolPinIndex < aSymbolPinCount; ++symbolPinIndex )
|
||||||
AddPin( { "", i + 1 } );
|
AddPin( { "", wxString::FromCDouble( symbolPinIndex + 1 ) } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,15 +132,15 @@ bool SIM_MODEL_SPICE::SetParamFromSpiceCode( const wxString& aParamName,
|
||||||
const wxString& aParamValue,
|
const wxString& aParamValue,
|
||||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
||||||
{
|
{
|
||||||
unsigned i = 0;
|
int paramIndex = 0;
|
||||||
|
|
||||||
for(; i < GetParamCount(); ++i )
|
for(; paramIndex < GetParamCount(); ++paramIndex )
|
||||||
{
|
{
|
||||||
if( GetParam( i ).info.name == aParamName.Lower() )
|
if( GetParam( paramIndex ).info.name == aParamName.Lower() )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i == GetParamCount() )
|
if( paramIndex == GetParamCount() )
|
||||||
{
|
{
|
||||||
// No parameter with this name found. Create a new one.
|
// No parameter with this name found. Create a new one.
|
||||||
std::unique_ptr<PARAM::INFO> paramInfo = std::make_unique<PARAM::INFO>();
|
std::unique_ptr<PARAM::INFO> paramInfo = std::make_unique<PARAM::INFO>();
|
||||||
|
@ -152,7 +152,7 @@ bool SIM_MODEL_SPICE::SetParamFromSpiceCode( const wxString& aParamName,
|
||||||
AddParam( *m_paramInfos.back() );
|
AddParam( *m_paramInfos.back() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetParam( i ).value->FromString( wxString( aParamValue ), aNotation );
|
return GetParam( paramIndex ).value->FromString( wxString( aParamValue ), aNotation );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,8 +250,8 @@ void SIM_MODEL_SPICE::parseLegacyPinsField( unsigned aSymbolPinCount,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Initially set all pins to Not Connected to match the legacy behavior.
|
// Initially set all pins to Not Connected to match the legacy behavior.
|
||||||
for( unsigned i = 0; i < GetPinCount(); ++i )
|
for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex )
|
||||||
SetPinSymbolPinNumber( static_cast<int>( i ), PIN::NOT_CONNECTED );
|
SetPinSymbolPinNumber( static_cast<int>( modelPinIndex ), "" );
|
||||||
|
|
||||||
tao::pegtl::string_input<> in( aLegacyPinsField.ToUTF8(), PINS_FIELD );
|
tao::pegtl::string_input<> in( aLegacyPinsField.ToUTF8(), PINS_FIELD );
|
||||||
std::unique_ptr<tao::pegtl::parse_tree::node> root;
|
std::unique_ptr<tao::pegtl::parse_tree::node> root;
|
||||||
|
@ -267,9 +267,18 @@ void SIM_MODEL_SPICE::parseLegacyPinsField( unsigned aSymbolPinCount,
|
||||||
THROW_IO_ERROR( e.what() );
|
THROW_IO_ERROR( e.what() );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned i = 0; i < root->children.size(); ++i )
|
for( int pinIndex = 0; pinIndex < static_cast<int>( root->children.size() ); ++pinIndex )
|
||||||
{
|
{
|
||||||
SetPinSymbolPinNumber( static_cast<int>( i ),
|
std::string symbolPinStr = root->children.at( pinIndex )->string();
|
||||||
std::stoi( root->children.at( i )->string() ) );
|
int symbolPinIndex = std::stoi( symbolPinStr ) - 1;
|
||||||
|
|
||||||
|
if( symbolPinIndex < 0 || symbolPinIndex >= static_cast<int>( aSymbolPinCount ) )
|
||||||
|
{
|
||||||
|
THROW_IO_ERROR( wxString::Format( _( "Invalid symbol pin index: '%s'" ),
|
||||||
|
symbolPinStr ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SetPinSymbolPinNumber( pinIndex, root->children.at( pinIndex )->string() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ public:
|
||||||
wxString GenerateSpiceItemName( const wxString& aRefName ) const override;
|
wxString GenerateSpiceItemName( const wxString& aRefName ) const override;
|
||||||
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
wxString GenerateSpiceItemLine( const wxString& aRefName,
|
||||||
const wxString& aModelName,
|
const wxString& aModelName,
|
||||||
|
const std::vector<wxString>& aSymbolPinNumbers,
|
||||||
const std::vector<wxString>& aPinNetNames ) const override;
|
const std::vector<wxString>& aPinNetNames ) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -81,7 +81,7 @@ void SIM_MODEL_SUBCKT::ReadSpiceCode( const wxString& aSpiceCode )
|
||||||
}
|
}
|
||||||
else if( subnode->is_type<SIM_MODEL_SUBCKT_SPICE_PARSER::dotSubcktPinName>() )
|
else if( subnode->is_type<SIM_MODEL_SUBCKT_SPICE_PARSER::dotSubcktPinName>() )
|
||||||
{
|
{
|
||||||
AddPin( { subnode->string(), GetPinCount() + 1 } );
|
AddPin( { subnode->string(), wxString::FromCDouble( GetPinCount() ) } );
|
||||||
}
|
}
|
||||||
else if( !hadParamValuePairs
|
else if( !hadParamValuePairs
|
||||||
&& subnode->is_type<SIM_MODEL_SUBCKT_SPICE_PARSER::paramValuePairs>() )
|
&& subnode->is_type<SIM_MODEL_SUBCKT_SPICE_PARSER::paramValuePairs>() )
|
||||||
|
@ -107,10 +107,10 @@ void SIM_MODEL_SUBCKT::ReadSpiceCode( const wxString& aSpiceCode )
|
||||||
}
|
}
|
||||||
else if( subnode->is_type<
|
else if( subnode->is_type<
|
||||||
SIM_MODEL_SUBCKT_SPICE_PARSER::number<SIM_VALUE::TYPE_INT,
|
SIM_MODEL_SUBCKT_SPICE_PARSER::number<SIM_VALUE::TYPE_INT,
|
||||||
SIM_MODEL_SUBCKT_SPICE_PARSER::NOTATION::SPICE>>()
|
SIM_MODEL_SUBCKT_SPICE_PARSER::NOTATION::SPICE>>()
|
||||||
|| subnode->is_type<
|
|| subnode->is_type<
|
||||||
SIM_MODEL_SUBCKT_SPICE_PARSER::number<SIM_VALUE::TYPE_FLOAT,
|
SIM_MODEL_SUBCKT_SPICE_PARSER::number<SIM_VALUE::TYPE_FLOAT,
|
||||||
SIM_MODEL_SUBCKT_SPICE_PARSER::NOTATION::SPICE>>() )
|
SIM_MODEL_SUBCKT_SPICE_PARSER::NOTATION::SPICE>>() )
|
||||||
{
|
{
|
||||||
wxASSERT( m_paramInfos.size() > 0 );
|
wxASSERT( m_paramInfos.size() > 0 );
|
||||||
m_paramInfos.back()->defaultValue = subnode->string();
|
m_paramInfos.back()->defaultValue = subnode->string();
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include <sch_sheet.h>
|
#include <sch_sheet.h>
|
||||||
#include <sch_sheet_pin.h>
|
#include <sch_sheet_pin.h>
|
||||||
#include <sch_view.h>
|
#include <sch_view.h>
|
||||||
|
#include <pin_numbers.h>
|
||||||
#include <schematic.h>
|
#include <schematic.h>
|
||||||
#include <advanced_config.h>
|
#include <advanced_config.h>
|
||||||
#include <sim/sim_plot_frame.h>
|
#include <sim/sim_plot_frame.h>
|
||||||
|
@ -62,7 +63,6 @@
|
||||||
#include <drawing_sheet/ds_proxy_undo_item.h>
|
#include <drawing_sheet/ds_proxy_undo_item.h>
|
||||||
#include <dialog_update_from_pcb.h>
|
#include <dialog_update_from_pcb.h>
|
||||||
#include <eda_list_dialog.h>
|
#include <eda_list_dialog.h>
|
||||||
#include <locale_io.h>
|
|
||||||
|
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
#include <wx_filename.h>
|
#include <wx_filename.h>
|
||||||
|
@ -733,7 +733,6 @@ void SCH_EDITOR_CONTROL::doCrossProbeSchToPcb( const TOOL_EVENT& aEvent, bool aF
|
||||||
|
|
||||||
int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
LOCALE_IO toggle;
|
|
||||||
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
|
||||||
SIM_PLOT_FRAME* simFrame = (SIM_PLOT_FRAME*) m_frame->Kiway().Player( FRAME_SIMULATOR, false );
|
SIM_PLOT_FRAME* simFrame = (SIM_PLOT_FRAME*) m_frame->Kiway().Player( FRAME_SIMULATOR, false );
|
||||||
|
|
||||||
|
@ -760,12 +759,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
if( item->Type() == SCH_PIN_T )
|
if( item->Type() == SCH_PIN_T )
|
||||||
{
|
{
|
||||||
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
|
LIB_PIN* pin = static_cast<SCH_PIN*>( item )->GetLibPin();
|
||||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
|
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
|
||||||
std::vector<SCH_PIN*> pins = symbol->GetAllPins();
|
std::vector<LIB_PIN*> pins = symbol->GetLibPins();
|
||||||
|
|
||||||
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
|
// TODO: We need to unify this library-model inheritance stuff into one
|
||||||
// abstraction.
|
// abstraction.
|
||||||
|
@ -813,7 +809,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
wxString ref = symbol->GetRef( &m_frame->GetCurrentSheet() );
|
wxString ref = symbol->GetRef( &m_frame->GetCurrentSheet() );
|
||||||
std::vector<wxString> currentNames = model->GenerateSpiceCurrentNames( ref );
|
std::vector<wxString> currentNames = model->GenerateSpiceCurrentNames( ref );
|
||||||
|
|
||||||
if( currentNames.size() == 0 )
|
if( currentNames.size() == 0 )
|
||||||
return true;
|
return true;
|
||||||
else if( currentNames.size() == 1 )
|
else if( currentNames.size() == 1 )
|
||||||
|
@ -822,11 +818,11 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int modelPinNumber = model->FindModelPinNumber( symbolPinNumber );
|
int modelPinIndex = model->FindModelPinIndex( pin->GetNumber() );
|
||||||
|
|
||||||
if( modelPinNumber > 0 )
|
if( modelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED )
|
||||||
{
|
{
|
||||||
wxString name = currentNames.at( modelPinNumber - 1 );
|
wxString name = currentNames.at( modelPinIndex );
|
||||||
simFrame->AddCurrentPlot( name );
|
simFrame->AddCurrentPlot( name );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue