We must infer a pinMap when inferring other fields for RLC passives.
Fixes https://gitlab.com/kicad/code/kicad/issues/13162
This commit is contained in:
parent
93879532f7
commit
b2e512bfab
|
@ -136,29 +136,32 @@ template <typename T_symbol, typename T_field>
|
|||
bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
{
|
||||
wxCommandEvent dummyEvent;
|
||||
T_field* valueField = m_symbol.FindField( wxT( "Value" ) );
|
||||
|
||||
// Infer RLC models if they aren't specified
|
||||
if( !m_symbol.FindField( SIM_MODEL::DEVICE_TYPE_FIELD )
|
||||
&& !m_symbol.FindField( SIM_MODEL::PARAMS_FIELD ) )
|
||||
{
|
||||
// std::pair<wxString, wxString> [ Sim.Type, Sim.Params ]
|
||||
auto inferredModel = SIM_MODEL::InferSimModel( m_symbol.GetPrefix(), valueField->GetText(),
|
||||
SIM_VALUE_GRAMMAR::NOTATION::SI );
|
||||
wxString modelType;
|
||||
wxString modelParams;
|
||||
wxString pinMap;
|
||||
|
||||
if( !inferredModel.second.IsEmpty() )
|
||||
if( SIM_MODEL::InferPassiveSimModel( m_symbol, false, SIM_VALUE_GRAMMAR::NOTATION::SI,
|
||||
&modelType, &modelParams, &pinMap ) )
|
||||
{
|
||||
m_fields.emplace_back( &m_symbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
m_fields.back().SetText( m_symbol.GetPrefix() );
|
||||
m_fields.back().SetText( m_symbol.GetPrefix().Left( 1 ) );
|
||||
|
||||
if( !inferredModel.first.IsEmpty() )
|
||||
if( !modelType.IsEmpty() )
|
||||
{
|
||||
m_fields.emplace_back( &m_symbol, -1, SIM_MODEL::TYPE_FIELD );
|
||||
m_fields.back().SetText( inferredModel.first );
|
||||
m_fields.back().SetText( modelType );
|
||||
}
|
||||
|
||||
m_fields.emplace_back( &m_symbol, -1, SIM_MODEL::PARAMS_FIELD );
|
||||
m_fields.back().SetText( inferredModel.second );
|
||||
m_fields.back().SetText( modelParams );
|
||||
|
||||
m_fields.emplace_back( &m_symbol, -1, SIM_MODEL::PINS_FIELD );
|
||||
m_fields.back().SetText( pinMap );
|
||||
|
||||
m_fields[ VALUE_FIELD ].SetText( wxT( "${SIM.PARAMS}" ) );
|
||||
}
|
||||
|
|
|
@ -235,24 +235,28 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
|||
if( !symbol->FindField( SIM_MODEL::DEVICE_TYPE_FIELD, false )
|
||||
&& !symbol->FindField( SIM_MODEL::PARAMS_FIELD, false ) )
|
||||
{
|
||||
// std::pair<wxString, wxString> [ Sim.Type, Sim.Params ]
|
||||
auto inferredModel = SIM_MODEL::InferSimModel( symbol->GetPrefix(),
|
||||
symbol->GetValueFieldText( true ),
|
||||
SIM_VALUE_GRAMMAR::NOTATION::SPICE );
|
||||
wxString modelType;
|
||||
wxString modelParams;
|
||||
wxString pinMap;
|
||||
|
||||
if( !inferredModel.second.IsEmpty() )
|
||||
if( SIM_MODEL::InferPassiveSimModel( *symbol, true,
|
||||
SIM_VALUE_GRAMMAR::NOTATION::SPICE,
|
||||
&modelType, &modelParams, &pinMap ) )
|
||||
{
|
||||
spiceItem.fields.emplace_back( symbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
spiceItem.fields.back().SetText( symbol->GetPrefix().Left( 1 ) );
|
||||
|
||||
if( !inferredModel.first.IsEmpty() )
|
||||
if( !modelType.IsEmpty() )
|
||||
{
|
||||
spiceItem.fields.emplace_back( symbol, -1, SIM_MODEL::TYPE_FIELD );
|
||||
spiceItem.fields.back().SetText( inferredModel.first );
|
||||
spiceItem.fields.back().SetText( modelType );
|
||||
}
|
||||
|
||||
spiceItem.fields.emplace_back( symbol, -1, SIM_MODEL::PARAMS_FIELD );
|
||||
spiceItem.fields.back().SetText( inferredModel.second );
|
||||
spiceItem.fields.back().SetText( modelParams );
|
||||
|
||||
spiceItem.fields.emplace_back( symbol, -1, SIM_MODEL::PINS_FIELD );
|
||||
spiceItem.fields.back().SetText( pinMap );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -183,24 +183,27 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, S
|
|||
if( !aSymbol.FindField( SIM_MODEL::DEVICE_TYPE_FIELD, false )
|
||||
&& !aSymbol.FindField( SIM_MODEL::PARAMS_FIELD, false ) )
|
||||
{
|
||||
// std::pair<wxString, wxString> [ Sim.Type, Sim.Params ]
|
||||
auto inferredModel = SIM_MODEL::InferSimModel( aSymbol.GetPrefix(),
|
||||
aSymbol.GetValueFieldText( true ),
|
||||
SIM_VALUE_GRAMMAR::NOTATION::SI );
|
||||
wxString modelType;
|
||||
wxString modelParams;
|
||||
wxString pinMap;
|
||||
|
||||
if( !inferredModel.second.IsEmpty() )
|
||||
if( SIM_MODEL::InferPassiveSimModel( aSymbol, true, SIM_VALUE_GRAMMAR::NOTATION::SI,
|
||||
&modelType, &modelParams, &pinMap ) )
|
||||
{
|
||||
fields.emplace_back( &aSymbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
fields.back().SetText( aSymbol.GetPrefix() );
|
||||
fields.back().SetText( aSymbol.GetPrefix().Left( 1 ) );
|
||||
|
||||
if( !inferredModel.first.IsEmpty() )
|
||||
if( !modelType.IsEmpty() )
|
||||
{
|
||||
fields.emplace_back( &aSymbol, -1, SIM_MODEL::TYPE_FIELD );
|
||||
fields.back().SetText( inferredModel.first );
|
||||
fields.back().SetText( modelType );
|
||||
}
|
||||
|
||||
fields.emplace_back( &aSymbol, -1, SIM_MODEL::PARAMS_FIELD );
|
||||
fields.back().SetText( inferredModel.second );
|
||||
fields.back().SetText( modelParams );
|
||||
|
||||
fields.emplace_back( &aSymbol, -1, SIM_MODEL::PINS_FIELD );
|
||||
fields.back().SetText( pinMap );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1033,13 +1033,18 @@ bool SIM_MODEL::requiresSpiceModelLine() const
|
|||
}
|
||||
|
||||
|
||||
// Returns [ Sim.Type, Sim.Params ]
|
||||
std::pair<wxString, wxString> SIM_MODEL::InferSimModel( const wxString& aPrefix,
|
||||
const wxString& aValue,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation )
|
||||
template <class T>
|
||||
bool SIM_MODEL::InferPassiveSimModel( T& aSymbol, bool aResolve,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString* aModelType,
|
||||
wxString* aModelParams, wxString* aPinMap )
|
||||
{
|
||||
wxString spiceModelType;
|
||||
wxString spiceModelParams;
|
||||
wxString aPrefix = aSymbol.GetPrefix();
|
||||
wxString aValue;
|
||||
|
||||
if( aResolve )
|
||||
aValue = aSymbol.FindField( VALUE_FIELD )->GetShownText();
|
||||
else
|
||||
aValue = aSymbol.FindField( VALUE_FIELD )->GetText();
|
||||
|
||||
if( !aValue.IsEmpty() )
|
||||
{
|
||||
|
@ -1047,18 +1052,18 @@ std::pair<wxString, wxString> SIM_MODEL::InferSimModel( const wxString& aPrefix,
|
|||
|| aPrefix.StartsWith( wxT( "L" ) )
|
||||
|| aPrefix.StartsWith( wxT( "C" ) ) )
|
||||
{
|
||||
wxRegEx passiveVal( wxT( "^"
|
||||
"([0-9\\. ]+)"
|
||||
"([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?"
|
||||
"([fFhHΩΩ𝛀𝛺𝝮]|ohm)?"
|
||||
"([-1-9 ]*)"
|
||||
"$" ) );
|
||||
wxRegEx idealVal( wxT( "^"
|
||||
"([0-9\\. ]+)"
|
||||
"([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?"
|
||||
"([fFhHΩΩ𝛀𝛺𝝮]|ohm)?"
|
||||
"([-1-9 ]*)"
|
||||
"$" ) );
|
||||
|
||||
if( passiveVal.Matches( aValue ) )
|
||||
if( idealVal.Matches( aValue ) ) // Ideal
|
||||
{
|
||||
wxString valuePrefix( passiveVal.GetMatch( aValue, 1 ) );
|
||||
wxString valueUnits( passiveVal.GetMatch( aValue, 2 ) );
|
||||
wxString valueSuffix( passiveVal.GetMatch( aValue, 6 ) );
|
||||
wxString valuePrefix( idealVal.GetMatch( aValue, 1 ) );
|
||||
wxString valueUnits( idealVal.GetMatch( aValue, 2 ) );
|
||||
wxString valueSuffix( idealVal.GetMatch( aValue, 6 ) );
|
||||
|
||||
if( aNotation == SIM_VALUE_GRAMMAR::NOTATION::SPICE )
|
||||
{
|
||||
|
@ -1071,25 +1076,62 @@ std::pair<wxString, wxString> SIM_MODEL::InferSimModel( const wxString& aPrefix,
|
|||
valueUnits = wxT( "M" );
|
||||
}
|
||||
|
||||
spiceModelParams = wxString::Format( wxT( "%s=\"%s%s\"" ),
|
||||
aPrefix.Left(1).Lower(),
|
||||
valuePrefix,
|
||||
valueUnits );
|
||||
aModelParams->Printf( wxT( "%s=\"%s%s\"" ),
|
||||
aPrefix.Left(1).Lower(),
|
||||
valuePrefix,
|
||||
valueUnits );
|
||||
}
|
||||
else // Behavioral
|
||||
{
|
||||
*aModelType = wxT( "=" );
|
||||
aModelParams->Printf( wxT( "%s=\"%s\"" ),
|
||||
aPrefix.Left(1).Lower(),
|
||||
aValue );
|
||||
}
|
||||
|
||||
std::vector<LIB_PIN*> pins = aSymbol.GetLibPins();
|
||||
|
||||
if( pins.size() == 2 )
|
||||
{
|
||||
aPinMap->Printf( wxT( "%s=+ %s=-" ),
|
||||
pins[0]->GetNumber(),
|
||||
pins[1]->GetNumber() );
|
||||
}
|
||||
else
|
||||
{
|
||||
spiceModelType = wxT( "=" );
|
||||
spiceModelParams = wxString::Format( wxT( "%s=\"%s\"" ),
|
||||
aPrefix.Left(1).Lower(),
|
||||
aValue );
|
||||
*aPinMap = wxEmptyString;
|
||||
|
||||
for( unsigned ii = 0; ii < pins.size(); ++ii )
|
||||
{
|
||||
if( ii > 0 )
|
||||
aPinMap->Append( wxS( " " ) );
|
||||
|
||||
aPinMap->Append( wxString::Format( wxT( "%s=%u" ),
|
||||
pins[ii]->GetNumber(),
|
||||
ii ) );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair( spiceModelType, spiceModelParams );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template bool SIM_MODEL::InferPassiveSimModel<SCH_SYMBOL>( SCH_SYMBOL& aSymbol, bool aResolve,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation,
|
||||
wxString* aModelType,
|
||||
wxString* aModelParams,
|
||||
wxString* aPinMap );
|
||||
template bool SIM_MODEL::InferPassiveSimModel<LIB_SYMBOL>( LIB_SYMBOL& aSymbol, bool aResolve,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation,
|
||||
wxString* aModelType,
|
||||
wxString* aModelParams,
|
||||
wxString* aPinMap );
|
||||
|
||||
|
||||
template <typename T_symbol, typename T_field>
|
||||
void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||
{
|
||||
|
@ -1180,7 +1222,12 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
|| netlistEnabled.StartsWith( wxT( "n" ) )
|
||||
|| netlistEnabled.StartsWith( wxT( "f" ) ) )
|
||||
{
|
||||
T_field enableField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::ENABLE_FIELD );
|
||||
netlistEnabledField->SetName( SIM_MODEL::ENABLE_FIELD );
|
||||
netlistEnabledField->SetText( wxT( "0" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
aSymbol.RemoveField( netlistEnabledField );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1212,10 +1259,9 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
|
||||
if( T_field* legacyPins = aSymbol.FindField( wxT( "Sim_Pins" ) ) )
|
||||
{
|
||||
// std::pair<wxString, wxString> [ Sim.Type, Sim.Params ]
|
||||
auto inferredModel = SIM_MODEL::InferSimModel( prefix, valueField->GetText(),
|
||||
SIM_VALUE_GRAMMAR::NOTATION::SI );
|
||||
bool isPassive = !inferredModel.second.IsEmpty();
|
||||
bool isPassive = prefix.StartsWith( wxT( "R" ) )
|
||||
|| prefix.StartsWith( wxT( "L" ) )
|
||||
|| prefix.StartsWith( wxT( "C" ) );
|
||||
|
||||
// Migrate pins from array of indexes to name-value-pairs
|
||||
wxArrayString pinIndexes;
|
||||
|
|
|
@ -522,12 +522,10 @@ public:
|
|||
}
|
||||
bool IsStoredInValue() const { return m_isStoredInValue; }
|
||||
|
||||
/**
|
||||
* Returns std::pair of [ Sim.Type, Sim.Params ]
|
||||
*/
|
||||
static std::pair<wxString, wxString> InferSimModel( const wxString& aPrefix,
|
||||
const wxString& aValue,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation );
|
||||
template <class T>
|
||||
static bool InferPassiveSimModel( T& aSymbol, bool aResolve,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString* aModelType,
|
||||
wxString* aModelParams, wxString* aPinMap );
|
||||
|
||||
template <class T_symbol, class T_field>
|
||||
static void MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject );
|
||||
|
|
Loading…
Reference in New Issue